Skip to content

[Android 14 Beta3] Can't control the device screenΒ #4074

Closed

Description

@DerekWuYD
  • I have read the FAQ.
  • I have searched in existing issues.

Environment

  • OS: debian
  • scrcpy version: v2.0
  • installation method: manual built
  • device model: Pixel 7 Pro
  • Android version: Android 14 Beta 3

Describe the bug
In Android 14 beta 3, mouse and keyboard input events are no longer valid.
Screencasting is working, but remote control has failed.

Start arguments : --force-adb-forward --no-audio

scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
x/server/scrcpy-server: 1 file pushed, 0 skipped. 74.6 MB/s (52911 bytes in 0.001s)
[server] INFO: Device: Google Pixel 7 Pro (Android 14)
[server] ERROR: Could not invoke method
java.lang.NoSuchMethodException: android.content.IClipboard$Stub$Proxy.addPrimaryClipChangedListener [interface android.content.IOnPrimaryClipChangedListener, class java.lang.String, class java.lang.String, int]
	at java.lang.Class.getMethod(Class.java:2937)
	at java.lang.Class.getMethod(Class.java:2449)
	at com.genymobile.scrcpy.wrappers.ClipboardManager.getAddPrimaryClipChangedListener(ClipboardManager.java:129)
	at com.genymobile.scrcpy.wrappers.ClipboardManager.addPrimaryClipChangedListener(ClipboardManager.java:139)
	at com.genymobile.scrcpy.Device.<init>(Device.java:100)
	at com.genymobile.scrcpy.Server.scrcpy(Server.java:64)
	at com.genymobile.scrcpy.Server.main(Server.java:381)
	at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
	at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:359)
[server] ERROR: Exception on thread Thread[Thread-2,5,main]
java.lang.AssertionError: java.lang.reflect.InvocationTargetException
	at com.genymobile.scrcpy.wrappers.ServiceManager.getInputManager(ServiceManager.java:72)
	at com.genymobile.scrcpy.Device.injectEvent(Device.java:192)
	at com.genymobile.scrcpy.Device.injectKeyEvent(Device.java:203)
	at com.genymobile.scrcpy.Device.pressReleaseKeycode(Device.java:211)
	at com.genymobile.scrcpy.Device.pressReleaseKeycode(Device.java:216)
	at com.genymobile.scrcpy.Controller.control(Controller.java:70)
	at com.genymobile.scrcpy.Controller.lambda$start$0$com-genymobile-scrcpy-Controller(Controller.java:90)
	at com.genymobile.scrcpy.Controller$$ExternalSyntheticLambda0.run(Unknown Source:2)
	at java.lang.Thread.run(Thread.java:1012)
Caused by: java.lang.reflect.InvocationTargetException
	at java.lang.reflect.Method.invoke(Native Method)
	at com.genymobile.scrcpy.wrappers.ServiceManager.getInputManager(ServiceManager.java:69)
	... 8 more
Caused by: java.lang.NullPointerException
	at java.util.Objects.requireNonNull(Objects.java:207)
	at android.hardware.input.InputManager.getInstance(InputManager.java:271)
	... 10 more

Activity

  1. DerekWuYD commented on Jun 9, 2023

    @DerekWuYD
    ContributorAuthor

    This method works both on Android 14 Beta3 and pervious version.

    Test result :

    scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
    x/server/scrcpy-server: 1 file pushed, 0 skipped. 133.6 MB/s (53187 bytes in 0.000s)
    [server] INFO: Device: Google Pixel 7 Pro (Android 14)
    [server] INFO: Using the InputManagerGlobal API
    INFO: Renderer: opengl
    INFO: OpenGL version: 4.5 (Compatibility Profile) Mesa 22.3.3
    ...
    
  2. added a commit that references this issue on Jun 9, 2023
    03a8a71
  3. rom1v commented on Jun 10, 2023

    @rom1v
    Collaborator

    Thank you again for the fix.

    However, I don't really understand the stacktrace:

    Caused by: java.lang.reflect.InvocationTargetException
    	at java.lang.reflect.Method.invoke(Native Method)
    	at com.genymobile.scrcpy.wrappers.ServiceManager.getInputManager(ServiceManager.java:69)
    	... 8 more
    Caused by: java.lang.NullPointerException
    	at java.util.Objects.requireNonNull(Objects.java:207)
    	at android.hardware.input.InputManager.getInstance(InputManager.java:271)
    	... 10 more
    

    Since you get an InvocationTargetException, the invocation fails (getInstanceMethod.invoke(null);), so getInstanceMethod != null, so the method InputManager.getInstance() still exists (?), but does not accept a null target (so it is not static anymore?).

    Could you please post your framework.jar so that I can understand?

    adb pull /system/framework/framework.jar
    
  4. forforksake commented on Jun 11, 2023

    @forforksake

    Could you please post your framework.jar so that I can understand?

    adb pull /system/framework/framework.jar
    

    Thanks to you both!

    I was having the exact same issue on Android 14 beta 3, on Pixel 6 Pro via Kubuntu 23.04

    framework.jar from my device =
    framework.tar.gz

  5. forforksake commented on Jun 11, 2023

    @forforksake

    This method works both on Android 14 Beta3 and pervious version.

    Test result :

    scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
    x/server/scrcpy-server: 1 file pushed, 0 skipped. 133.6 MB/s (53187 bytes in 0.000s)
    [server] INFO: Device: Google Pixel 7 Pro (Android 14)
    [server] INFO: Using the InputManagerGlobal API
    INFO: Renderer: opengl
    INFO: OpenGL version: 4.5 (Compatibility Profile) Mesa 22.3.3
    ...
    

    Works perfectly - saved my life man, just smashed my screen and to my horror when I loaded scrcpy for the first time on A14 - disaster! Thanks both

  6. DerekWuYD commented on Jun 12, 2023

    @DerekWuYD
    ContributorAuthor

    #4074 (comment)

    Actually android.hardware.input.InputManager.getInstance still exist, but there's some changes in the function body.
    Let's figure out the best solution when Android 14 source code release on AOSP : )

  7. rom1v commented on Jun 12, 2023

    @rom1v
    Collaborator

    framework.jar from my device =
    framework.tar.gz

    Thank you πŸ‘

    So in Android 13 (current AOSP master), here is the implementation of InputManager.getInstance():

        @UnsupportedAppUsage
        public static InputManager getInstance() {
            synchronized (InputManager.class) {
                if (sInstance == null) {
                    try {
                        sInstance = new InputManager(IInputManager.Stub
                                .asInterface(ServiceManager.getServiceOrThrow(Context.INPUT_SERVICE)));
                    } catch (ServiceNotFoundException e) {
                        throw new IllegalStateException(e);
                    }
                }
                return sInstance;
            }
        }

    In Android 14 (the version from your framework.jar), the new InputManager.getInstance() implementation is:

        @Deprecated
        public static InputManager getInstance() {
            return (InputManager) ((Application) Objects.requireNonNull(ActivityThread.currentApplication())).getSystemService(InputManager.class);
        }

    And InputManagerGlobal.getInstance():

        public static InputManagerGlobal getInstance() {
            InputManagerGlobal inputManagerGlobal;
            IBinder b;
            synchronized (InputManagerGlobal.class) {
                if (sInstance == null && (b = ServiceManager.getService("input")) != null) {
                    sInstance = new InputManagerGlobal(IInputManager.Stub.asInterface(b));
                }
                inputManagerGlobal = sInstance;
            }
            return inputManagerGlobal;
        }
  8. added a commit that references this issue on Jun 12, 2023
    34adddc
  9. icantremember commented on Jun 13, 2023

    @icantremember

    Works perfectly - saved my life man, just smashed my screen and to my horror when I loaded scrcpy for the first time on A14 - disaster! Thanks both

    Sorry if I'm not following, but what "Works perfectly"? Am I just not seeing a command line switch that has options allowing this to work?

    Thanks.

  10. rom1v commented on Jun 13, 2023

    @rom1v
    Collaborator
  11. added a commit that references this issue on Jun 13, 2023
    5bd7514
  12. icantremember commented on Jun 13, 2023

    @icantremember

    Thanks for the reply, but I think I'm in a bit over my head. That commit would only help me if I were to build from source on my own, right? There's no (pre)release that has it yet, right?

  13. rom1v commented on Jun 13, 2023

    @rom1v
    Collaborator

    That commit would only help me if I were to build from source on my own, right? There's no (pre)release that has it yet, right?

    That's correct.

    But I plan to release a new version soon (v2.1, maybe next week), which is basically what is on dev branch, currently on commit 5bd7514 (+ the future SDL 2.28 not released yet). So if you beta-test it and report regressions/problems, I can provide a build πŸ˜„

    Here it is:

    (check git log for new features and command line options)

  14. icantremember commented on Jun 13, 2023

    @icantremember

    But I plan to release a new version soon (v2.1, maybe next week), which is basically what is on dev branch, currently on commit 5bd7514 (+ the future SDL 2.28 not released yet). So if you beta-test it and report regressions/problems, I can provide a build πŸ˜„

    Awesome. Can confirm that mouse/keyboard control is working well in this version. Anything else specific you need tested?

  15. Yaoojq commented on Jun 28, 2023

    @Yaoojq

    I can see the screen on my computer, but I can't control the phone from the computer

    [server] INFO: Device: Xiaomi 22011211C (Android 13)
    [server] ERROR: Could not invoke method
    java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at com.genymobile.scrcpy.wrappers.InputManager.injectInputEvent(InputManager.java:37)
    at com.genymobile.scrcpy.Device.injectEvent(Device.java:192)
    at com.genymobile.scrcpy.Device.injectKeyEvent(Device.java:203)
    at com.genymobile.scrcpy.Device.pressReleaseKeycode(Device.java:211)
    at com.genymobile.scrcpy.Device.pressReleaseKeycode(Device.java:216)
    at com.genymobile.scrcpy.Controller.control(Controller.java:70)
    at com.genymobile.scrcpy.Controller.lambda$start$0$com-genymobile-scrcpy-Controller(Controller.java:90)
    at com.genymobile.scrcpy.Controller$$ExternalSyntheticLambda0.run(Unknown Source:2)
    at java.lang.Thread.run(Thread.java:1012)
    Caused by: java.lang.SecurityException: Injecting input events requires the caller (or the source of the instrumentation, if any) to have the INJECT_EVENTS permission.
    at android.os.Parcel.createExceptionOrNull(Parcel.java:3011)
    at android.os.Parcel.createException(Parcel.java:2995)
    at android.os.Parcel.readException(Parcel.java:2978)
    at android.os.Parcel.readException(Parcel.java:2920)
    at android.hardware.input.IInputManager$Stub$Proxy.injectInputEventToTarget(IInputManager.java:1294)
    at android.hardware.input.InputManager.injectInputEvent(InputManager.java:1153)
    at android.hardware.input.InputManager.injectInputEvent(InputM

  16. DerekWuYD commented on Jun 28, 2023

    @DerekWuYD
    ContributorAuthor
  17. Yaoojq commented on Jun 28, 2023

    @Yaoojq

    It is normal after the device is restarted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions