mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-03 06:39:39 +00:00
Add util function to get the APK version
Use "dumpsys package com.genymobile.scrcpy" to get the APK version.
This commit is contained in:
parent
91dee4f245
commit
be70f0218d
5 changed files with 126 additions and 0 deletions
|
@ -435,6 +435,7 @@ sc_adb_list_devices(struct sc_intr *intr, unsigned flags,
|
||||||
"Please report an issue.");
|
"Please report an issue.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#undef BUFSIZE
|
||||||
|
|
||||||
// It is parsed as a NUL-terminated string
|
// It is parsed as a NUL-terminated string
|
||||||
buf[r] = '\0';
|
buf[r] = '\0';
|
||||||
|
@ -758,3 +759,54 @@ sc_adb_get_installed_apk_path(struct sc_intr *intr, const char *serial,
|
||||||
|
|
||||||
return sc_adb_parse_installed_apk_path(buf);
|
return sc_adb_parse_installed_apk_path(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
sc_adb_get_installed_apk_version(struct sc_intr *intr, const char *serial,
|
||||||
|
unsigned flags) {
|
||||||
|
assert(serial);
|
||||||
|
const char *const argv[] =
|
||||||
|
SC_ADB_COMMAND("-s", serial, "shell", "dumpsys", "package",
|
||||||
|
SC_ANDROID_PACKAGE);
|
||||||
|
|
||||||
|
sc_pipe pout;
|
||||||
|
sc_pid pid = sc_adb_execute_p(argv, flags, &pout);
|
||||||
|
if (pid == SC_PROCESS_NONE) {
|
||||||
|
LOGD("Could not execute \"dumpsys package\"");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "dumpsys package" output can be huge (e.g. 16k), but versionName is at
|
||||||
|
// the beginning, typically in the first 1024 bytes (64k should be enough
|
||||||
|
// for the whole output anyway)
|
||||||
|
#define BUFSIZE 65536
|
||||||
|
char *buf = malloc(BUFSIZE);
|
||||||
|
if (!buf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ssize_t r = sc_pipe_read_all_intr(intr, pid, pout, buf, BUFSIZE - 1);
|
||||||
|
sc_pipe_close(pout);
|
||||||
|
|
||||||
|
bool ok = process_check_success_intr(intr, pid, "dumpsys package", flags);
|
||||||
|
if (!ok) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r == -1) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert((size_t) r < BUFSIZE);
|
||||||
|
#undef BUFSIZE
|
||||||
|
// if r == sizeof(buf), then the output is truncated, but we don't care,
|
||||||
|
// versionName is at the beginning in practice, and is unlikely to be
|
||||||
|
// truncated at 64k
|
||||||
|
|
||||||
|
// It is parsed as a NUL-terminated string
|
||||||
|
buf[r] = '\0';
|
||||||
|
|
||||||
|
char *version = sc_adb_parse_installed_apk_version(buf);
|
||||||
|
free(buf);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
|
@ -123,4 +123,11 @@ char *
|
||||||
sc_adb_get_installed_apk_path(struct sc_intr *intr, const char *serial,
|
sc_adb_get_installed_apk_path(struct sc_intr *intr, const char *serial,
|
||||||
unsigned flags);
|
unsigned flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the version of the installed APK for com.genymobile.scrcpy (if any)
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
sc_adb_get_installed_apk_version(struct sc_intr *intr, const char *serial,
|
||||||
|
unsigned flags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -253,3 +253,34 @@ sc_adb_parse_installed_apk_path(char *str) {
|
||||||
|
|
||||||
return strdup(s);
|
return strdup(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
sc_adb_parse_installed_apk_version(const char *str) {
|
||||||
|
// str is the (beginning of the) output of `dumpsys package`
|
||||||
|
// We want to extract the version string from a line starting with 4 spaces
|
||||||
|
// then `versionName=` then the version string.
|
||||||
|
|
||||||
|
#define VERSION_NAME_PREFIX "\n versionName="
|
||||||
|
char *s = strstr(str, VERSION_NAME_PREFIX);
|
||||||
|
if (!s) {
|
||||||
|
// Not found
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s+= sizeof(VERSION_NAME_PREFIX) - 1;
|
||||||
|
|
||||||
|
size_t len = strspn(s, "0123456789.");
|
||||||
|
if (!len) {
|
||||||
|
LOGW("Unexpected version name with no value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *version = malloc(len + 1);
|
||||||
|
if (!version) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(version, s, len);
|
||||||
|
version[len] = '\0';
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
|
@ -38,4 +38,13 @@ sc_adb_parse_device_ip(char *str);
|
||||||
char *
|
char *
|
||||||
sc_adb_parse_installed_apk_path(char *str);
|
sc_adb_parse_installed_apk_path(char *str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the package version from the output of
|
||||||
|
* `adb shell dumpsys package <package>`
|
||||||
|
*
|
||||||
|
* The parameter must be a NUL-terminated string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
sc_adb_parse_installed_apk_version(const char *str);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -263,6 +263,32 @@ static void test_apk_path_invalid(void) {
|
||||||
assert(!path);
|
assert(!path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_apk_version(void) {
|
||||||
|
char str[] =
|
||||||
|
"Key Set Manager:\n"
|
||||||
|
" [com.genymobile.scrcpy]\n"
|
||||||
|
" Signing KeySets: 128\n"
|
||||||
|
"\n"
|
||||||
|
"Packages:\n"
|
||||||
|
" Package [com.genymobile.scrcpy] (89abcdef):\n"
|
||||||
|
" userId=12345\n"
|
||||||
|
" pkg=Package{012345 com.genymobile.scrcpy}\n"
|
||||||
|
" codePath=/data/app/~~abcdef==/com.genymobile.scrcpy-012345==\n"
|
||||||
|
" resourcePath=/data/app/~~abcdef==/com.genymobile.scrcpy-013245==\n"
|
||||||
|
" primaryCpuAbi=null\n"
|
||||||
|
" secondaryCpuAbi=null\n"
|
||||||
|
" versionCode=12400 minSdk=21 targetSdk=31\n"
|
||||||
|
" versionName=1.24\n"
|
||||||
|
" splits=[base]\n"
|
||||||
|
" apkSigningVersion=2\n"
|
||||||
|
" applicationInfo=ApplicationInfo{012345 com.genymobile.scrcpy}\n";
|
||||||
|
|
||||||
|
const char *expected = "1.24";
|
||||||
|
char *version = sc_adb_parse_installed_apk_version(str);
|
||||||
|
assert(!strcmp(version, expected));
|
||||||
|
free(version);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
(void) argc;
|
(void) argc;
|
||||||
(void) argv;
|
(void) argv;
|
||||||
|
@ -287,6 +313,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
test_apk_path();
|
test_apk_path();
|
||||||
test_apk_path_invalid();
|
test_apk_path_invalid();
|
||||||
|
test_apk_version();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue