Adapt call() on ContentProvider for Android 11

This commit in AOSP framework_base added a parameter "attributionTag" to
the call() method:
12ac3f406f%5E%21/#F17

As a consequence, the method did not exist, so scrcpy used the legacy
call() method (using the authority "unknown") as a fallback, which fails
for security reasons.

Fixes #1468 <https://github.com/Genymobile/scrcpy/issues/1468>
This commit is contained in:
Romain Vimont 2020-09-13 21:35:11 +02:00
parent bd9f656933
commit ae758f99d6

View file

@ -35,7 +35,7 @@ public class ContentProvider implements Closeable {
private final IBinder token; private final IBinder token;
private Method callMethod; private Method callMethod;
private boolean callMethodLegacy; private int callMethodVersion;
ContentProvider(ActivityManager manager, Object provider, String name, IBinder token) { ContentProvider(ActivityManager manager, Object provider, String name, IBinder token) {
this.manager = manager; this.manager = manager;
@ -46,12 +46,20 @@ public class ContentProvider implements Closeable {
private Method getCallMethod() throws NoSuchMethodException { private Method getCallMethod() throws NoSuchMethodException {
if (callMethod == null) { if (callMethod == null) {
try { try {
callMethod = provider.getClass().getMethod("call", String.class, String.class, String.class, String.class, Bundle.class); callMethod = provider.getClass()
.getMethod("call", String.class, String.class, String.class, String.class, String.class, Bundle.class);
callMethodVersion = 0;
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
// old version // old versions
callMethod = provider.getClass().getMethod("call", String.class, String.class, String.class, Bundle.class); try {
callMethodLegacy = true; callMethod = provider.getClass().getMethod("call", String.class, String.class, String.class, String.class, Bundle.class);
callMethodVersion = 1;
} catch (NoSuchMethodException e2) {
callMethod = provider.getClass().getMethod("call", String.class, String.class, String.class, Bundle.class);
callMethodVersion = 2;
}
} }
} }
return callMethod; return callMethod;
@ -61,10 +69,16 @@ public class ContentProvider implements Closeable {
try { try {
Method method = getCallMethod(); Method method = getCallMethod();
Object[] args; Object[] args;
if (!callMethodLegacy) { switch (callMethodVersion) {
args = new Object[]{ServiceManager.PACKAGE_NAME, "settings", callMethod, arg, extras}; case 0:
} else { args = new Object[]{ServiceManager.PACKAGE_NAME, null, "settings", callMethod, arg, extras};
args = new Object[]{ServiceManager.PACKAGE_NAME, callMethod, arg, extras}; break;
case 1:
args = new Object[]{ServiceManager.PACKAGE_NAME, "settings", callMethod, arg, extras};
break;
default:
args = new Object[]{ServiceManager.PACKAGE_NAME, callMethod, arg, extras};
break;
} }
return (Bundle) method.invoke(provider, args); return (Bundle) method.invoke(provider, args);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {