Skip to content
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

Given calling package android does not match caller's uid #4639

Closed
2 tasks done
tomaszstachera opened this issue Feb 2, 2024 · 25 comments
Closed
2 tasks done

Given calling package android does not match caller's uid #4639

tomaszstachera opened this issue Feb 2, 2024 · 25 comments

Comments

@tomaszstachera
Copy link

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

Environment

  • OS: macOs
  • scrcpy version: 2.3.1
  • installation method: brew
  • device model: Onyx Boox Tab Ultra C
  • Android version: 11

Describe the bug
Cannot share device screen. It suddenly stopped working.

scrcpy -v
scrcpy 2.3.1 <https://github.com/Genymobile/scrcpy>

Dependencies (compiled / linked):
 - SDL: 2.28.5 / 2.28.5
 - libavcodec: 60.3.100 / 60.3.100
 - libavformat: 60.3.100 / 60.3.100
 - libavutil: 58.2.100 / 58.2.100
 - libusb: - / 1.0.26
 adb devices -l
List of devices attached
D545DC1E               device usb:336592896X product:BOOX model:TabUltraC device:BOOX transport_id:6
emulator-5554          offline transport_id:2
scrcpy -d -V debug
scrcpy 2.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  D545DC1E                        device  TabUltraC
INFO:         (tcpip)  emulator-5554                  offline
DEBUG: Device serial: D545DC1E
DEBUG: Using server: /usr/local/Cellar/scrcpy/2.3.1/share/scrcpy/scrcpy-server
/usr/local/Cellar/scrcpy/2.3.1/share/scrcpy/scrcpy-server: 1 file pushed, 0 skipped. 31.9 MB/s (66007 bytes in 0.002s)
[server] INFO: Device: [ONYX] ONYX TabUltraC (Android 11)
[server] ERROR: Given calling package android does not match caller's uid 2000
java.lang.SecurityException: Given calling package android does not match caller's uid 2000
        at android.os.Parcel.createExceptionOrNull(Parcel.java:2374)
        at android.os.Parcel.createException(Parcel.java:2358)
        at android.os.Parcel.readException(Parcel.java:2341)
        at android.os.Parcel.readException(Parcel.java:2283)
        at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:5808)
        at android.app.ActivityThread.acquireProvider(ActivityThread.java:6937)
        at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:2912)
        at android.content.ContentResolver.acquireProvider(ContentResolver.java:2470)
        at android.provider.Settings$ContentProviderHolder.getProvider(Settings.java:2596)
        at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:2725)
        at android.provider.Settings$Global.getStringForUser(Settings.java:13469)
        at android.provider.Settings$Global.getString(Settings.java:13457)
        at android.provider.Settings$Global.getInt(Settings.java:13662)
        at android.hardware.input.InputManager.setupPointerNaturalRolling(InputManager.java:321)
        at android.hardware.input.InputManager.registerPointerSettingObserver(InputManager.java:291)
        at android.hardware.input.InputManager.<init>(InputManager.java:283)
        at android.hardware.input.InputManager.getInstance(InputManager.java:357)
        at android.view.KeyCharacterMap.load(KeyCharacterMap.java:334)
        at com.genymobile.scrcpy.Controller.<init>(Controller.java:35)
        at com.genymobile.scrcpy.Server.scrcpy(Server.java:127)
        at com.genymobile.scrcpy.Server.internalMain(Server.java:244)
        at com.genymobile.scrcpy.Server.main(Server.java:199)
        at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
        at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:399)
Caused by: android.os.RemoteException: Remote stack trace:
        at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:7715)
        at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2425)
        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2926)
        at android.os.Binder.execTransactInternal(Binder.java:1154)
        at android.os.Binder.execTransact(Binder.java:1123)

DEBUG: Server disconnected
DEBUG: Server terminated
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
DEBUG: Receiver stopped
INFO: Renderer: metal
DEBUG: Trilinear filtering disabled (not an OpenGL renderer
DEBUG: Using icon: /usr/local/Cellar/scrcpy/2.3.1/share/icons/hicolor/256x256/apps/scrcpy.png
DEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audio': starting thread
ERROR: Demuxer 'video': stream disabled due to connection error
ERROR: Demuxer 'audio': stream disabled due to connection error
ERROR: Demuxer error
DEBUG: quit...
@rom1v
Copy link
Collaborator

rom1v commented Feb 3, 2024

By any chance, is the device rooted? #1606

@tomaszstachera
Copy link
Author

Nope

@tomaszstachera
Copy link
Author

 adb -d shell id
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:shell:s0

@fivesprites
Copy link

Having exact same issue.

OS: Windows 11
Scrcpy: V2.3.1
Device: Boox Note Air2 Plus

Note: DevTools Android App used to enable Developer options and USB debugging (https://play.google.com/store/apps/details?id=cn.trinea.android.developertools&pcampaignid=web_share)

[server] INFO: Device: [ONYX] ONYX NoteAir2P (Android 11)
[server] ERROR: Given calling package android does not match caller's uid 2000
java.lang.SecurityException: Given calling package android does not match caller's uid 2000
at android.os.Parcel.createExceptionOrNull(Parcel.java:2374)
at android.os.Parcel.createException(Parcel.java:2358)
at android.os.Parcel.readException(Parcel.java:2341)
at android.os.Parcel.readException(Parcel.java:2283)
at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:5808)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:6937)
at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:2912)
at android.content.ContentResolver.acquireProvider(ContentResolver.java:2470)
at android.provider.Settings$ContentProviderHolder.getProvider(Settings.java:2596)
at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:2725)
at android.provider.Settings$Global.getStringForUser(Settings.java:13469)
at android.provider.Settings$Global.getString(Settings.java:13457)
at android.provider.Settings$Global.getInt(Settings.java:13662)
at android.hardware.input.InputManager.setupPointerNaturalRolling(InputManager.java:321)
at android.hardware.input.InputManager.registerPointerSettingObserver(InputManager.java:291)
at android.hardware.input.InputManager.(InputManager.java:283)
at android.hardware.input.InputManager.getInstance(InputManager.java:357)
at android.view.KeyCharacterMap.load(KeyCharacterMap.java:334)
at com.genymobile.scrcpy.Controller.(Controller.java:35)
at com.genymobile.scrcpy.Server.scrcpy(Server.java:127)
at com.genymobile.scrcpy.Server.internalMain(Server.java:244)
at com.genymobile.scrcpy.Server.main(Server.java:199)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:399)
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:7715)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2425)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2926)
at android.os.Binder.execTransactInternal(Binder.java:1154)
at android.os.Binder.execTransact(Binder.java:1123)

ERROR: Could not retrieve device information
ERROR: Server connection failed

@rom1v
Copy link
Collaborator

rom1v commented Feb 12, 2024

Check in your system settings or developer options if there is an option to give a permission related to clipboard.

@fivesprites
Copy link

Just had a dig through and can't find anything in any settings related to clipboard.

@havogt
Copy link

havogt commented Feb 27, 2024

It seems (if you don't need audio) scrcpy --no-audio works as suggested in #4527.

@zzfhadr
Copy link

zzfhadr commented May 16, 2024

scrcpy --video-source=camera --no-audio
scrcpy 2.4 <https://github.com/Genymobile/scrcpy>
INFO: Camera video source: control disabled
INFO: ADB device found:
INFO:     -->   (usb)  3414257783000YW                 device  V2148A
F:\little tools\scrcpy-win64-v2.4\scrcpy-server: 1 file pushed, 0 skipped. 48.6 MB/s (69007 bytes in 0.001s)
[server] INFO: Device: [vivo] vivo V2148A (Android 13)
[server] INFO: Using camera '0'
[server] ERROR: Exception on thread Thread[video,5,main]
java.lang.SecurityException: Given calling package android does not match caller's uid 2000
        at android.os.Parcel.createExceptionOrNull(Parcel.java:3025)
        at android.os.Parcel.createException(Parcel.java:3009)
        at android.os.Parcel.readException(Parcel.java:2992)
        at android.os.Parcel.readException(Parcel.java:2934)
        at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:6142)
        at android.app.ActivityThread.acquireProvider(ActivityThread.java:7689)
        at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:3503)
        at android.content.ContentResolver.acquireProvider(ContentResolver.java:2542)
        at android.provider.Settings$ContentProviderHolder.getProvider(Settings.java:2955)
        at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:3182)
        at android.provider.Settings$Global.getStringForUser(Settings.java:16192)
        at android.provider.Settings$Global.getString(Settings.java:16166)
        at android.hardware.camera2.vivo_ext.VivoCameraUtils.sendStartPreviewBroadCast(VivoCameraUtils.java:199)
        at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:770)
        at android.hardware.camera2.CameraManager.openCameraForUid(CameraManager.java:1035)
        at android.hardware.camera2.CameraManager.openCameraForUid(CameraManager.java:1056)
        at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:871)
        at com.genymobile.scrcpy.CameraCapture.openCamera(CameraCapture.java:241)
        at com.genymobile.scrcpy.CameraCapture.init(CameraCapture.java:86)
        at com.genymobile.scrcpy.SurfaceEncoder.streamScreen(SurfaceEncoder.java:55)
        at com.genymobile.scrcpy.SurfaceEncoder.lambda$start$0$com-genymobile-scrcpy-SurfaceEncoder(SurfaceEncoder.java:253)
        at com.genymobile.scrcpy.SurfaceEncoder$$ExternalSyntheticLambda0.run(Unknown Source:4)
        at java.lang.Thread.run(Thread.java:1015)
Caused by: android.os.RemoteException: Remote stack trace:
        at com.android.server.am.ContentProviderHelper.getContentProvider(ContentProviderHelper.java:174)
        at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:7413)
        at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2840)
        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3158)
        at android.os.Binder.execTransactInternal(Binder.java:1346)
INFO: Renderer: direct3d
ERROR: Demuxer 'video': stream disabled due to connection error
ERROR: Demuxer error

@rom1v
Copy link
Collaborator

rom1v commented May 16, 2024

Same as #4349 (comment) (I don't know the cause)

@prodiamondyt
Copy link

prodiamondyt commented Oct 4, 2024

I found a solution for this on my Vivo Y21T, I had to download the older version of scrcpy which is v2.2 for now!
"Note: I haven't tried the other older versions yet of when it would stop working or etc.. like v2.2 upper"
"Edit, only v2.2 works for me for now.."

And fsr, the newer versions don't work on mine and I had this similar error too but this thingy worked for me ^w^

@rom1v
Copy link
Collaborator

rom1v commented Oct 4, 2024

2.2 works for you, what about 2.3?

@Ercilan
Copy link

Ercilan commented Oct 16, 2024

Not professional android developer, just learning it for interest.
After my research, here are some my experiences and thoughts.


The cause of all issues related to Given calling package android does not match caller's uid is:
In some special rom, the related code in the trace(it is usually some manager, such as inputManager, audioManager or other object which not use FakeContext) wants to use contentProvider by calling getContentProvider(But in other common device, they wouldn't do this). And scrcpy's FakeContext doesn't override the getContentResolver method, so that the rom will use the "android" context to get a contentProvider with the package name called "android"(UID is 0). In the binder side, the caller uid is 2000. So this is why it makes conflicts.

Because the manger is initialized somewhere(i don't look into it) with "android" system context, I tried to patch the context in the manger. But after changing context, it gives me that it can't find the app. Because scrcpy is not a app, it can't pass through the getContentResolver's permission check.

But, after looking into the ApplicationContentResolver and the content command in shell, i find out that we could use the getContentProviderExternal (I just find that it is also used in the [ActivityManager](https://github.com/Genymobile/scrcpy/blob/665ccb32f5306ebd866dc0d99f4d08ed2aeb91c3/server/src/main/java/com/genymobile/scrcpy/wrappers/ActivityManager.java#L67) at this time). I try to write a custom class like ApplicationContentResolver to return the content provider from getContentProviderExternal method. Then override getContentResolver to return the resolver. And it works for my need: show a view(in a device of mine, the view's click listener will call audioManager to play sound effect and cause the "getContentProvider" problem).

However, due to the lack of understanding of Android I still not override the release method in ApplicationContentResolver properly (even though it seems to work fine), so there might still be some issues in my code. And also i use special android sdk, I share the idea here first.

If want to set image to clipboard, it also needs a contentResolver: ClipData.newUri(context.getContentResolver(), "URI", uri)


There may be some mistakes in this paragraph, because I did it some time ago, and now I have forgotten it a little, and my English is not very good, I have tried to decrease mistakes.

@rom1v
Copy link
Collaborator

rom1v commented Oct 16, 2024

@Ercilan Thank you for your investigations.

Could you post a branch with your changes?

@Ercilan
Copy link

Ercilan commented Oct 16, 2024

@Ercilan Thank you for your investigations.

Could you post a branch with your changes?

@rom1v I'm going to sleep now. It's midnight im my place🌃.
I can provide some code here now.
The key part is to i use a special android sdk to skip long reflect code and use IContentProvider directly (it may be confused when develop other ordinary app). So i can use it like:

package com.genymobile.scrcpy.wrappers;

import android.annotation.SuppressLint;
import android.app.ActivityThread;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentProvider;
import android.os.Binder;
import android.os.IBinder;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;

public class ApplicationContentResolver extends ContentResolver {
    private final ActivityThread mMainThread;

    public ApplicationContentResolver(Context context, ActivityThread mainThread) {
        super(context);
        mMainThread = Objects.requireNonNull(mainThread);
    }

    @Override
    protected IContentProvider acquireProvider(Context context, String auth) {
        return ServiceManager.getActivityManager().getContentProviderExternal(ContentProvider.getAuthorityWithoutUserId(auth), new Binder());
    }

    @Override
    protected IContentProvider acquireExistingProvider(Context context, String auth) {
        // it has never been called...
        return mMainThread.acquireExistingProvider(context, ContentProvider.getAuthorityWithoutUserId(auth), resolveUserIdFromAuthority(auth), true);
    }

    @Override
    public boolean releaseProvider(IContentProvider provider) {
        // todo maybe need to release ContentProviderExternal
        return mMainThread.releaseProvider(provider, true);
    }

    @Override
    protected IContentProvider acquireUnstableProvider(Context c, String auth) {
//        return mMainThread.acquireProvider(c, ContentProvider.getAuthorityWithoutUserId(auth), resolveUserIdFromAuthority(auth), false);
        // I just update here today(24/10/16), clipboardManager call this. not tested enough 
        return ServiceManager.getActivityManager().getContentProviderExternal(ContentProvider.getAuthorityWithoutUserId(auth), new Binder());
    }

    @Override
    public boolean releaseUnstableProvider(IContentProvider icp) {
        // todo maybe need to release ContentProviderExternal
        return mMainThread.releaseProvider(icp, false);
    }

    @SuppressLint("DiscouragedPrivateApi")
    @Override
    public void unstableProviderDied(IContentProvider icp) {
        try {
            // mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
            Method handleUnstableProviderDied = ActivityThread.class.getDeclaredMethod("handleUnstableProviderDied", IBinder.class, boolean.class);
            handleUnstableProviderDied.invoke(mMainThread, icp.asBinder(), true);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    @SuppressLint("SoonBlockedPrivateApi")
    @Override
    public void appNotRespondingViaProvider(IContentProvider icp) {
        try {
            // mMainThread.appNotRespondingViaProvider(icp.asBinder());
            Method appNotRespondingViaProvider = ActivityThread.class.getDeclaredMethod("appNotRespondingViaProvider", IBinder.class);
            appNotRespondingViaProvider.invoke(mMainThread, icp.asBinder());
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    protected int resolveUserIdFromAuthority(String auth) {
        return ContentProvider.getUserIdFromAuthority(auth, getUserId());
    }
}

In the ActivityManager:

...

@TargetApi(Build.VERSION_CODES.Q)
    public IContentProvider getContentProviderExternal(String name, IBinder token) {
        try {
            Method method = getGetContentProviderExternalMethod();
            Object[] args;
            if (getContentProviderExternalMethodNewVersion) {
                // new version
                args = new Object[]{name, FakeContext.ROOT_UID, token, null};
            } else {
                // old version
                args = new Object[]{name, FakeContext.ROOT_UID, token};
            }
            // ContentProviderHolder providerHolder = getContentProviderExternal(...);
            Object providerHolder = method.invoke(manager, args);
            if (providerHolder == null) {
                return null;
            }
            // IContentProvider provider = providerHolder.provider;
            Field providerField = providerHolder.getClass().getDeclaredField("provider");
            providerField.setAccessible(true);
            Object provider = providerField.get(providerHolder);
            return (IContentProvider) provider;
        } catch (ReflectiveOperationException e) {
            Ln.e("Could not invoke method", e);
            return null;
        }
    }

    private ContentProvider getContentProviderExternalInternal(String name, IBinder token) {
        IContentProvider provider = getContentProviderExternal(name, token);
        return new ContentProvider(this, provider, name, token);
    }

    void removeContentProviderExternal(String name, IBinder token) {
        try {
            Method method = getRemoveContentProviderExternalMethod();
            method.invoke(manager, name, token);
        } catch (ReflectiveOperationException e) {
            Ln.e("Could not invoke method", e);
        }
    }

    public ContentProvider createSettingsProvider() {
        return getContentProviderExternalInternal("settings", new Binder());
    }

...

FakeContext:

...

    private final ApplicationContentResolver mContentResolver;
    private static boolean isAudioManagerPatched = false;

    private FakeContext() {
        super(Workarounds.getSystemContext());
        mContentResolver = new ApplicationContentResolver(this, (ActivityThread) Workarounds.ACTIVITY_THREAD);
    }

    /**
     * getContentResolver without app
     */
    @Override
    public ContentResolver getContentResolver() {
        try {
            return mContentResolver;
        } catch (Exception e) {
            Ln.e("getContentResolver Exception", e);
        }
        return super.getContentResolver();
    }


 @Override
    public Object getSystemService(String name) {
        Object service = super.getSystemService(name);
        switch (name) {
            case Context.AUDIO_SERVICE:
                if (!isAudioManagerPatched) {
                    patchAudioManagerContext(service);
                    isAudioManagerPatched = true;
                }
                break;
//             ...
        }

        return service;
    }

    @SuppressLint("SoonBlockedPrivateApi")
    private void patchAudioManagerContext(Object service) {
        try {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) {
                return;
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                Method setContextMethod = AudioManager.class.getDeclaredMethod("setContext", Context.class);
                setContextMethod.setAccessible(true);
                setContextMethod.invoke(service, this);
            } else {
                Field mContextField = AudioManager.class.getDeclaredField("mContext");
                mContextField.setAccessible(true);
                mContextField.set(service, this);
            }
        } catch (Exception e) {
            Ln.e("patchAudioManagerContext Exception", e);
        }
    }

@Ercilan
Copy link

Ercilan commented Oct 17, 2024

@Ercilan Thank you for your investigations.
Could you post a branch with your changes?

@rom1v I'm going to sleep now. It's midnight im my place🌃. I can provide some code here now. The key part is to i use a special android sdk to skip long reflect code and use IContentProvider directly (it may be confused when develop other ordinary app). So i can use it like:

Today, I take a look at the process of invoking system services and made some additions.


The system obtains system services through ContextImpl, and the internal context of the system services is this ContextImpl instance. Therefore, getContentResolver is also directly accessed via ContextImpl. There is no way to override or extend ContextImpl to directly return our custom contentResolver. Although we can try to make FakeContext wrap the correct "com.android.shell" package name, it still doesn't solve the issue of java.lang.SecurityException: Unable to find app for caller android.app.IApplicationThread$Stub$Proxy@8d2cdb4 (pid=13488) when getting content provider settings.

My solution here is to intercept and reflectively modify the internal context in the manager by overriding FakeContext.getSystemService, so that a specific manager will eventually call FakeContext's getContentResolver. Then, I will use an instance of FakeContext somewhere to trigger this interception and modification. For example, I can trigger the patch by fetching clipboardManager through FakeContext in some part of scrcpy, or I can directly use the instance of FakeContext to construct views, etc.

Some manager may need a handler, i already have one for View.


I reviewed the error log for this issue, specifically InputManager.getInstance, which uses the context set in com.genymobile.scrcpy.Workarounds#fillAppContext(FakeContext). So, I think my approach should be able to address this issue.

@yume-chan
Copy link
Contributor

Looks like the runtime type checking is so loose that even this works: https://github.com/Genymobile/scrcpy/compare/dev...yume-chan:scrcpy:feat/content-resolver?expand=1

It can be compiled with standard android.jar.


I have tested this on Android 10, 11, 13, 14 on real devices, and 15 on emulator using this patch:

diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java
index e0adeea0..4f75d104 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Server.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Server.java
@@ -25,6 +25,7 @@ import com.genymobile.scrcpy.video.SurfaceCapture;
 import com.genymobile.scrcpy.video.SurfaceEncoder;
 import com.genymobile.scrcpy.video.VideoSource;
 
+import android.content.ContentResolver;
 import android.os.BatteryManager;
 import android.os.Build;
 
@@ -169,6 +170,14 @@ public final class Server {
 
         Workarounds.apply();
 
+        try {
+            ContentResolver contentResolver = FakeContext.get().getContentResolver();
+            int airplaneMode = android.provider.Settings.Global.getInt(contentResolver, android.provider.Settings.Global.AIRPLANE_MODE_ON);
+            Ln.i("Airplane mode: " + airplaneMode);
+        } catch (Exception e) {
+            Ln.e("Get content resolver failed", e);
+        }
+
         List<AsyncProcessor> asyncProcessors = new ArrayList<>();
 
         DesktopConnection connection = DesktopConnection.open(scid, tunnelForward, video, audio, control, sendDummyByte);

Prebuilt server: scrcpy-server.zip

@mengyanshou
Copy link
Contributor

Looks like the runtime type checking is so loose that even this works: https://github.com/Genymobile/scrcpy/compare/dev...yume-chan:scrcpy:feat/content-resolver?expand=1

It can be compiled with standard android.jar.

I have tested this on Android 10, 11, 13, 14 on real devices, and 15 on emulator using this patch:

diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java
index e0adeea0..4f75d104 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Server.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Server.java
@@ -25,6 +25,7 @@ import com.genymobile.scrcpy.video.SurfaceCapture;
 import com.genymobile.scrcpy.video.SurfaceEncoder;
 import com.genymobile.scrcpy.video.VideoSource;
 
+import android.content.ContentResolver;
 import android.os.BatteryManager;
 import android.os.Build;
 
@@ -169,6 +170,14 @@ public final class Server {
 
         Workarounds.apply();
 
+        try {
+            ContentResolver contentResolver = FakeContext.get().getContentResolver();
+            int airplaneMode = android.provider.Settings.Global.getInt(contentResolver, android.provider.Settings.Global.AIRPLANE_MODE_ON);
+            Ln.i("Airplane mode: " + airplaneMode);
+        } catch (Exception e) {
+            Ln.e("Get content resolver failed", e);
+        }
+
         List<AsyncProcessor> asyncProcessors = new ArrayList<>();
 
         DesktopConnection connection = DesktopConnection.open(scid, tunnelForward, video, audio, control, sendDummyByte);

Prebuilt server: scrcpy-server.zip

thanks, your server binary is ok on Android15(Xiaomi 15),but when i use your code to compile my own server binary, audio is broken again, and i cannot use build_without_gradle.sh to build, i just can use Android Studio to build, any idea? thanks.

@yume-chan
Copy link
Contributor

audio is broken again

Any error output?

and i cannot use build_without_gradle.sh to build

Maybe need to add android/content/IContentProvider.java here:

SRC=( \
com/genymobile/scrcpy/*.java \
com/genymobile/scrcpy/audio/*.java \
com/genymobile/scrcpy/control/*.java \
com/genymobile/scrcpy/device/*.java \
com/genymobile/scrcpy/util/*.java \
com/genymobile/scrcpy/video/*.java \
com/genymobile/scrcpy/wrappers/*.java \
)

@mengyanshou
Copy link
Contributor

this is compile error
截屏2024-11-11 04 55 58

I will provide the runtime error log for you later. It is probably still a uid 2000 problem. I guess it is a problem with the IContentProvider definition

@yume-chan
Copy link
Contributor

I fixed building with build_without_gradle.sh: yume-chan@d836006

@mengyanshou
Copy link
Contributor

mengyanshou commented Nov 11, 2024

I fixed building with build_without_gradle.sh: yume-chan@d836006

thanks, Everything goes well!

rom1v pushed a commit that referenced this issue Nov 11, 2024
The source files are encoded in UTF-8.

Refs <#4639 (comment)>

Signed-off-by: Romain Vimont <rom@rom1v.com>
@rom1v
Copy link
Collaborator

rom1v commented Nov 11, 2024

I fixed building with build_without_gradle.sh: yume-chan@d836006

Thank you, I allowed myself to merge it into dev: c0e2e27

@yume-chan
Copy link
Contributor

Thank you, I allowed myself to merge it into dev: c0e2e27

FYI, I ran build_without_gradle.sh in a clean Ubuntu docker container, and javac throws hundreds of errors in https://github.com/Genymobile/scrcpy/blob/master/server/src/main/java/com/genymobile/scrcpy/control/KeyComposition.java about encoding. A quick Google search shows -encoding UTF-8 fixes it.

@rom1v
Copy link
Collaborator

rom1v commented Nov 11, 2024

FYI, I ran build_without_gradle.sh in a clean Ubuntu docker container

AFAIK, in all Linux distros, the default encoding is UTF-8. I don't know why it's not the case in your container. I reproduce the problem if I explicitly pass javac -encoding ISO-8859-1 ….

Anyway, specifying the encoding explicitly is the right thing to do.

rom1v pushed a commit that referenced this issue Nov 12, 2024
This avoids the following error on some devices:

    Given calling package android does not match caller's uid 2000

Refs #4639 comment <#4639 (comment)>
Fixes #4639 <#4639>

Signed-off-by: Romain Vimont <rom@rom1v.com>
@rom1v
Copy link
Collaborator

rom1v commented Nov 12, 2024

Please test #5476.

rom1v pushed a commit that referenced this issue Nov 14, 2024
This avoids the following error on some devices:

    Given calling package android does not match caller's uid 2000

Refs #4639 comment <#4639 (comment)>
Fixes #4639 <#4639>

Signed-off-by: Romain Vimont <rom@rom1v.com>
@rom1v rom1v closed this as completed in 91373d9 Nov 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants