RikkaApps / HiddenApiRefinePlugin

A Gradle plugin that improves the experience when developing Android apps, especially system tools, that use hidden APIs.
MIT License
272 stars 17 forks source link

[Ask for help]ApplicationPackageManager cannot be cast to android.view.SurfaceControl #8

Closed Moderpach closed 2 years ago

Moderpach commented 2 years ago

I want to call a hidden api in android.view.SurfaceControl. So I call this in my app module.

Refine.unsafeCast<SurfaceControlHidden>(context.packageManager).internalDisplayToken

And my "hidden-api" module is like

package android.view;

import dev.rikka.tools.refine.RefineAs;

@RefineAs(SurfaceControl.class)
public class SurfaceControlHidden {

    private native long[] nativeGetPhysicalDisplayIds();
    private native IBinder nativeGetPhysicalDisplayToken(long physicalDisplayId);

    public long[] getPhysicalDisplayIds() {
        return nativeGetPhysicalDisplayIds();
    }

    public IBinder getPhysicalDisplayToken(long physicalDisplayId) {
        return nativeGetPhysicalDisplayToken(physicalDisplayId);
    }

    public IBinder getInternalDisplayToken() {
        final long[] physicalDisplayIds = getPhysicalDisplayIds();
        if (physicalDisplayIds.length == 0) {
            return null;
        }
        return getPhysicalDisplayToken(physicalDisplayIds[0]);
    }

}

But when the app actually call the hidden api, it causes

java.lang.ClassCastException: android.app.ApplicationPackageManager cannot be cast to android.view.SurfaceControl

Did I make a mistake somewhere? Please help point it out. Thank you very much.

RikkaW commented 2 years ago
Refine.unsafeCast<SurfaceControlHidden>(context.packageManager)

You are casting context.packageManager (android.content.pm.PackageManager) to android.view.SurfaceControl which is obviously wrong.

Method getInternalDisplayToken is a static method, so correct your stub class and call SurfaceControlHidden.getInternalDisplayToken directly.

Moderpach commented 2 years ago

很抱歉又来叨扰您了。 如果我直接调用SurfaceControlHidden.getInternalDisplayToken会出现错误 java.lang.NoSuchMethodError: No static method getInternalDisplayToken()Landroid/os/IBinder; in class Landroid/view/SurfaceControl; or its super classes (declaration of 'android.view.SurfaceControl' appears in /system/framework/framework.jar!classes3.dex)我对此毫无头绪,请问如何解决。

另外是只要获取了Shizuku权限就可以只通过HiddenApiRefinePlugin中的方法就可以直接访问到Hidden-API了吗?还是要继续使用Shizuku-API里的"Using Shizuku APIs: Remote binder call"中的方法。

Kr328 commented 2 years ago

很抱歉又来叨扰您了。 如果我直接调用SurfaceControlHidden.getInternalDisplayToken会出现错误 java.lang.NoSuchMethodError: No static method getInternalDisplayToken()Landroid/os/IBinder; in class Landroid/view/SurfaceControl; or its super classes (declaration of 'android.view.SurfaceControl' appears in /system/framework/framework.jar!classes3.dex)我对此毫无头绪,请问如何解决。

另外是只要获取了Shizuku权限就可以只通过HiddenApiRefinePlugin中的方法就可以直接访问到Hidden-API了吗?还是要继续使用Shizuku-API里的"Using Shizuku APIs: Remote binder call"中的方法。

这个 API 可能是受到 Android 非 SDK API 限制

你有在使用绕过该限制的库吗 类似 AndroidHiddenApiBypass

Moderpach commented 2 years ago

@Kr328 非常感谢,通过 https://github.com/LSPosed/AndroidHiddenApiBypass 我已经可以调用到API。 但是像 SurfaceControl.setDisplayBrightness()等这些设定类的方法,调用他们并没有任何作用,请问android是对这些方法有什么限制吗?

Kr328 commented 2 years ago

@Kr328 非常感谢,通过 https://github.com/LSPosed/AndroidHiddenApiBypass 我已经可以调用到API。 但是像 SurfaceControl.setDisplayBrightness()等这些设定类的方法,调用他们并没有任何作用,请问android是对这些方法有什么限制吗?

这类操作一般仅有系统进程或者特权应用拥有权限访问

你可以使用 SuiShizuku 来在特权进程下调用 API

具体可以在这俩仓库的 README.md 了解如何使用

在使用时可能会需要了解 API 的具体逻辑 可以使用 Code Search 阅读源代码

再具体的我无法提供帮助

RikkaW commented 2 years ago

Binder 是 Client/Server 的结构,SurfaceControl.setDisplayBrightness() 是客户端,所以要自己找服务端的实现来看有什么权限检查。