Compare commits

..

1 Commits

Author SHA1 Message Date
Romain Vimont
29b47ad5ac Adapt call() on ContentProvider for Android 12
Android 12 changed one of the call() overloads with a new parameter
AttributionSource. Adapt the wrapper.

Fixes #2402 <https://github.com/Genymobile/scrcpy/issues/2402>
2021-06-19 09:16:54 +02:00
3 changed files with 19 additions and 40 deletions

View File

@@ -81,20 +81,14 @@ show_adb_installation_msg() {
static void static void
show_adb_err_msg(enum process_result err, const char *const argv[]) { show_adb_err_msg(enum process_result err, const char *const argv[]) {
#define MAX_COMMAND_STRING_LEN 1024 char buf[512];
char *buf = malloc(MAX_COMMAND_STRING_LEN);
if (!buf) {
LOGE("Failed to execute (could not allocate error message)");
return;
}
switch (err) { switch (err) {
case PROCESS_ERROR_GENERIC: case PROCESS_ERROR_GENERIC:
argv_to_string(argv, buf, MAX_COMMAND_STRING_LEN); argv_to_string(argv, buf, sizeof(buf));
LOGE("Failed to execute: %s", buf); LOGE("Failed to execute: %s", buf);
break; break;
case PROCESS_ERROR_MISSING_BINARY: case PROCESS_ERROR_MISSING_BINARY:
argv_to_string(argv, buf, MAX_COMMAND_STRING_LEN); argv_to_string(argv, buf, sizeof(buf));
LOGE("Command not found: %s", buf); LOGE("Command not found: %s", buf);
LOGE("(make 'adb' accessible from your PATH or define its full" LOGE("(make 'adb' accessible from your PATH or define its full"
"path in the ADB environment variable)"); "path in the ADB environment variable)");
@@ -104,38 +98,29 @@ show_adb_err_msg(enum process_result err, const char *const argv[]) {
// do nothing // do nothing
break; break;
} }
free(buf);
} }
process_t process_t
adb_execute(const char *serial, const char *const adb_cmd[], size_t len) { adb_execute(const char *serial, const char *const adb_cmd[], size_t len) {
const char *cmd[len + 4];
int i; int i;
process_t process; process_t process;
cmd[0] = get_adb_command();
const char **argv = malloc((len + 4) * sizeof(*argv));
if (!argv) {
return PROCESS_NONE;
}
argv[0] = get_adb_command();
if (serial) { if (serial) {
argv[1] = "-s"; cmd[1] = "-s";
argv[2] = serial; cmd[2] = serial;
i = 3; i = 3;
} else { } else {
i = 1; i = 1;
} }
memcpy(&argv[i], adb_cmd, len * sizeof(const char *)); memcpy(&cmd[i], adb_cmd, len * sizeof(const char *));
argv[len + i] = NULL; cmd[len + i] = NULL;
enum process_result r = process_execute(argv, &process); enum process_result r = process_execute(cmd, &process);
if (r != PROCESS_SUCCESS) { if (r != PROCESS_SUCCESS) {
show_adb_err_msg(r, argv); show_adb_err_msg(r, cmd);
process = PROCESS_NONE; return PROCESS_NONE;
} }
free(argv);
return process; return process;
} }

View File

@@ -6,9 +6,7 @@
#include "util/log.h" #include "util/log.h"
#include "util/str_util.h" #include "util/str_util.h"
#define CMD_MAX_LEN 8192 static int
static bool
build_cmd(char *cmd, size_t len, const char *const argv[]) { build_cmd(char *cmd, size_t len, const char *const argv[]) {
// Windows command-line parsing is WTF: // Windows command-line parsing is WTF:
// <http://daviddeley.com/autohotkey/parameters/parameters.htm#WINPASS> // <http://daviddeley.com/autohotkey/parameters/parameters.htm#WINPASS>
@@ -17,9 +15,9 @@ build_cmd(char *cmd, size_t len, const char *const argv[]) {
size_t ret = xstrjoin(cmd, argv, ' ', len); size_t ret = xstrjoin(cmd, argv, ' ', len);
if (ret >= len) { if (ret >= len) {
LOGE("Command too long (%" PRIsizet " chars)", len - 1); LOGE("Command too long (%" PRIsizet " chars)", len - 1);
return false; return -1;
} }
return true; return 0;
} }
enum process_result enum process_result
@@ -29,14 +27,13 @@ process_execute(const char *const argv[], HANDLE *handle) {
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
si.cb = sizeof(si); si.cb = sizeof(si);
char *cmd = malloc(CMD_MAX_LEN); char cmd[256];
if (!cmd || !build_cmd(cmd, CMD_MAX_LEN, argv)) { if (build_cmd(cmd, sizeof(cmd), argv)) {
*handle = NULL; *handle = NULL;
return PROCESS_ERROR_GENERIC; return PROCESS_ERROR_GENERIC;
} }
wchar_t *wide = utf8_to_wide_char(cmd); wchar_t *wide = utf8_to_wide_char(cmd);
free(cmd);
if (!wide) { if (!wide) {
LOGC("Could not allocate wide char string"); LOGC("Could not allocate wide char string");
return PROCESS_ERROR_GENERIC; return PROCESS_ERROR_GENERIC;

View File

@@ -47,13 +47,12 @@ public class ContentProvider implements Closeable {
this.token = token; this.token = token;
} }
@SuppressLint("PrivateApi")
private Method getCallMethod() throws NoSuchMethodException { private Method getCallMethod() throws NoSuchMethodException {
if (callMethod == null) { if (callMethod == null) {
try { try {
@SuppressLint("PrivateApi")
Class<?> attributionSourceClass = Class.forName("android.content.AttributionSource"); Class<?> attributionSourceClass = Class.forName("android.content.AttributionSource");
callMethod = provider.getClass().getMethod("call", attributionSourceClass, String.class, String.class, String.class, Bundle.class); callMethod = provider.getClass().getMethod("call", attributionSourceClass, String.class, String.class, String.class, Bundle.class);
callMethodVersion = 0;
} catch (NoSuchMethodException | ClassNotFoundException e0) { } catch (NoSuchMethodException | ClassNotFoundException e0) {
// old versions // old versions
try { try {
@@ -74,7 +73,6 @@ public class ContentProvider implements Closeable {
return callMethod; return callMethod;
} }
@SuppressLint("PrivateApi")
private Object getAttributionSource() private Object getAttributionSource()
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
if (attributionSource == null) { if (attributionSource == null) {
@@ -104,8 +102,7 @@ public class ContentProvider implements Closeable {
default: default:
args = new Object[]{ServiceManager.PACKAGE_NAME, callMethod, arg, extras}; args = new Object[]{ServiceManager.PACKAGE_NAME, callMethod, arg, extras};
break; break;
} } return (Bundle) method.invoke(provider, args);
return (Bundle) method.invoke(provider, args);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) { } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) {
Ln.e("Could not invoke method", e); Ln.e("Could not invoke method", e);
return null; return null;