-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android 12: Stay Awake setting fails #2402
Comments
Thank you for the report. Could you please execute diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
index f8393e59..c24651be 100644
--- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
+++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
@@ -45,6 +45,8 @@ public class ContentProvider implements Closeable {
}
private Method getCallMethod() throws NoSuchMethodException {
+ for (Method m : provider.getClass().getDeclaredMethods())
+ Ln.i("=== " + m);
if (callMethod == null) {
try { Here is a binary (to replace in your v1.17 release):
Thank you. |
Replaced binary
|
AttributionSource is new I guess. Only reference I can find is https://cs.android.com/androidx/android-test/+/master:services/speakeasy/java/androidx/test/services/speakeasy/client/ToolConnection.java;l=197?q=android.content.AttributionSource |
Oh, they now pass an instance of
We can try to pass diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
index f8393e59..f0a121c1 100644
--- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
+++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
@@ -2,6 +2,7 @@ package com.genymobile.scrcpy.wrappers;
import com.genymobile.scrcpy.Ln;
+import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.IBinder;
@@ -57,8 +58,20 @@ public class ContentProvider implements Closeable {
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;
+ try {
+ callMethod = provider.getClass().getMethod("call", String.class, String.class, String.class, Bundle.class);
+ callMethodVersion = 2;
+ } catch (NoSuchMethodException e3) {
+ try {
+ @SuppressLint("PrivateApi")
+ Class<?> attributionSourceClass = Class.forName("android.content.AttributionSource");
+ callMethod = provider.getClass()
+ .getMethod("call", attributionSourceClass, String.class, String.class, String.class, Bundle.class);
+ callMethodVersion = 3;
+ } catch (ClassNotFoundException cnfe) {
+ throw new AssertionError(cnfe);
+ }
+ }
}
}
}
@@ -76,9 +89,12 @@ public class ContentProvider implements Closeable {
case 1:
args = new Object[]{ServiceManager.PACKAGE_NAME, "settings", callMethod, arg, extras};
break;
- default:
+ case 2:
args = new Object[]{ServiceManager.PACKAGE_NAME, callMethod, arg, extras};
break;
+ default:
+ args = new Object[]{null, "settings", callMethod, arg, extras};
+ break;
}
return (Bundle) method.invoke(provider, args);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
My bad, I'm an idiot. wrong phone. |
Looks the same on the Pixel. Too many phones, had swapped to the Samsung to see what the call() looked like on Android 11.
|
Let's try with only the fix (disabling all the other method versions): diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
index f8393e59..4cc68253 100644
--- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
+++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
@@ -2,6 +2,7 @@ package com.genymobile.scrcpy.wrappers;
import com.genymobile.scrcpy.Ln;
+import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.IBinder;
@@ -48,18 +49,13 @@ public class ContentProvider implements Closeable {
if (callMethod == null) {
try {
+ @SuppressLint("PrivateApi")
+ Class<?> attributionSourceClass = Class.forName("android.content.AttributionSource");
callMethod = provider.getClass()
- .getMethod("call", String.class, String.class, String.class, String.class, String.class, Bundle.class);
- callMethodVersion = 0;
- } catch (NoSuchMethodException e) {
- // old versions
- try {
- 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;
- }
+ .getMethod("call", attributionSourceClass, String.class, String.class, String.class, Bundle.class);
+ callMethodVersion = -1;
+ } catch (ClassNotFoundException cnfe) {
+ throw new AssertionError(cnfe);
}
}
return callMethod;
@@ -70,14 +66,8 @@ public class ContentProvider implements Closeable {
Method method = getCallMethod();
Object[] args;
switch (callMethodVersion) {
- case 0:
- args = new Object[]{ServiceManager.PACKAGE_NAME, null, "settings", 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};
+ args = new Object[]{null, "settings", callMethod, arg, extras};
break;
}
return (Bundle) method.invoke(provider, args);
|
I've got a separate app with just the ContentProvider in, you are right, it doesn't like passing null. It does like the code from that test app
|
Let's create an diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
index f8393e59..b6d7f5f0 100644
--- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
+++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ContentProvider.java
@@ -2,6 +2,7 @@ package com.genymobile.scrcpy.wrappers;
import com.genymobile.scrcpy.Ln;
+import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.IBinder;
@@ -48,18 +49,13 @@ public class ContentProvider implements Closeable {
if (callMethod == null) {
try {
+ @SuppressLint("PrivateApi")
+ Class<?> attributionSourceClass = Class.forName("android.content.AttributionSource");
callMethod = provider.getClass()
- .getMethod("call", String.class, String.class, String.class, String.class, String.class, Bundle.class);
- callMethodVersion = 0;
- } catch (NoSuchMethodException e) {
- // old versions
- try {
- 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;
- }
+ .getMethod("call", attributionSourceClass, String.class, String.class, String.class, Bundle.class);
+ callMethodVersion = -1;
+ } catch (ClassNotFoundException cnfe) {
+ throw new AssertionError(cnfe);
}
}
return callMethod;
@@ -70,18 +66,16 @@ public class ContentProvider implements Closeable {
Method method = getCallMethod();
Object[] args;
switch (callMethodVersion) {
- case 0:
- args = new Object[]{ServiceManager.PACKAGE_NAME, null, "settings", 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};
+ 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);
+ Object attributionSource = cl.getDeclaredMethod("build").invoke(builder);
+ args = new Object[]{attributionSource, "settings", callMethod, arg, extras};
break;
}
return (Bundle) method.invoke(provider, args);
- } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
+ } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) {
Ln.e("Could not invoke method", e);
return null;
}
|
LGTM. I guess it immediately cleans up that its changed it due to the other issue.
|
Ok, good, thank you. Will do a proper fix. |
I implemented a proper fix on Please confirm that it works for you before I merge it into Here are binaries (replace both files in v1.17):
|
No errors in the console and screen mirrors |
Great! Thank you. Merged into |
Environment
Describe the bug
In addition to the display error in #2129. It looks like writing the settings for stay-awake fails under Android 12.
The error looks a lot like #1468 so I guess Google have changed the methods again. In https://cs.android.com/android/platform/superproject/+/android-s-preview-1:frameworks/base/core/java/android/provider/Settings.java;drc=android-s-preview-1;l=14487
The text was updated successfully, but these errors were encountered: