Use AttributionSource from FakeContext

FakeContext already provides an AttributeSource instance.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
This commit is contained in:
Romain Vimont 2023-01-31 22:31:15 +01:00
parent a5541b3476
commit 9a815ceba8

View file

@ -1,9 +1,12 @@
package com.genymobile.scrcpy.wrappers; package com.genymobile.scrcpy.wrappers;
import com.genymobile.scrcpy.FakeContext;
import com.genymobile.scrcpy.Ln; import com.genymobile.scrcpy.Ln;
import com.genymobile.scrcpy.SettingsException; import com.genymobile.scrcpy.SettingsException;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.AttributionSource;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
@ -51,11 +54,10 @@ public class ContentProvider implements Closeable {
@SuppressLint("PrivateApi") @SuppressLint("PrivateApi")
private Method getCallMethod() throws NoSuchMethodException { private Method getCallMethod() throws NoSuchMethodException {
if (callMethod == null) { if (callMethod == null) {
try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
Class<?> attributionSourceClass = Class.forName("android.content.AttributionSource"); callMethod = provider.getClass().getMethod("call", AttributionSource.class, String.class, String.class, String.class, Bundle.class);
callMethod = provider.getClass().getMethod("call", attributionSourceClass, String.class, String.class, String.class, Bundle.class);
callMethodVersion = 0; callMethodVersion = 0;
} catch (NoSuchMethodException | ClassNotFoundException e0) { } else {
// old versions // old versions
try { try {
callMethod = provider.getClass() callMethod = provider.getClass()
@ -75,40 +77,29 @@ public class ContentProvider implements Closeable {
return callMethod; return callMethod;
} }
@SuppressLint("PrivateApi")
private Object getAttributionSource()
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
if (attributionSource == null) {
Class<?> cl = Class.forName("android.content.AttributionSource$Builder");
Object builder = cl.getConstructor(int.class).newInstance(ServiceManager.USER_ID);
cl.getDeclaredMethod("setPackageName", String.class).invoke(builder, ServiceManager.PACKAGE_NAME);
attributionSource = cl.getDeclaredMethod("build").invoke(builder);
}
return attributionSource;
}
private Bundle call(String callMethod, String arg, Bundle extras) private Bundle call(String callMethod, String arg, Bundle extras)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
try { try {
Method method = getCallMethod(); Method method = getCallMethod();
Object[] args; Object[] args;
switch (callMethodVersion) {
case 0: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && callMethodVersion == 0) {
args = new Object[]{getAttributionSource(), "settings", callMethod, arg, extras}; args = new Object[]{FakeContext.get().getAttributionSource(), "settings", callMethod, arg, extras};
break; } else {
case 1: switch (callMethodVersion) {
args = new Object[]{ServiceManager.PACKAGE_NAME, null, "settings", callMethod, arg, extras}; case 1:
break; args = new Object[]{ServiceManager.PACKAGE_NAME, null, "settings", callMethod, arg, extras};
case 2: break;
args = new Object[]{ServiceManager.PACKAGE_NAME, "settings", callMethod, arg, extras}; case 2:
break; args = new Object[]{ServiceManager.PACKAGE_NAME, "settings", callMethod, arg, extras};
default: break;
args = new Object[]{ServiceManager.PACKAGE_NAME, callMethod, arg, extras}; default:
break; 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 | ClassNotFoundException | InstantiationException e) { } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
Ln.e("Could not invoke method", e); Ln.e("Could not invoke method", e);
throw e; throw e;
} }