Подтвердить что ты не робот

Как обычные разработчики пытаются использовать isPermissionRevokedByPolicy()?

Уровень API добавлен isPermissionRevokedByPolicy() on PackageManager. Предполагается вернуть false, если запрошенное разрешение заблокировано для определенного пакета "по правилам":

Обычно владелец устройства или владелец профиля могут применять такую ​​политику.

Есть ли что-нибудь, что может сделать разработчик, чтобы вызвать isPermissionRevokedByPolicy() для возврата false для некоторой комбинации пакетов/разрешений, не пройдя весь набор синаниганов Android for Work?

4b9b3361

Ответ 1

Конечно, я могу ошибаться, но, похоже, короткий ответ - "нет, нет", к сожалению.

Немного более расширенный ответ: Здесь код ApplicationPackageManager:

@Override
public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
    try {
        return mPM.isPermissionRevokedByPolicy(permName, pkgName, mContext.getUserId());
    } catch (RemoteException e) {
        throw new RuntimeException("Package manager has died", e);
    }
}

где mPM -

private final IPackageManager mPM;

Он инициализируется в конструкторе, который вызывается ContextImpl.getPackageManager():

@Override
public PackageManager getPackageManager() {
    if (mPackageManager != null) {
        return mPackageManager;
    }

    IPackageManager pm = ActivityThread.getPackageManager();
    if (pm != null) {
        // Doesn't matter if we make more than one instance.
        return (mPackageManager = new ApplicationPackageManager(this, pm));
    }

    return null;
}

(исходный код)

Идя глубже и смотря в ActivityThread.getPackageManager():

public static IPackageManager getPackageManager() {
    if (sPackageManager != null) {
        //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
        return sPackageManager;
    }
    IBinder b = ServiceManager.getService("package");
    //Slog.v("PackageManager", "default service binder = " + b);
    sPackageManager = IPackageManager.Stub.asInterface(b);
    //Slog.v("PackageManager", "default service = " + sPackageManager);
    return sPackageManager;
}

(исходный код)

Все эти шаги я делал, чтобы найти фактическую реализацию isPermissionRevokedByPolicy btw. Затем мне пришлось найти, кто расширяет IPackageManager.Stub - it PackageManagerService (исходный код).

Итак, вот фактическая реализация:

@Override
public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
    if (UserHandle.getCallingUserId() != userId) {
        mContext.enforceCallingPermission(
                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                "isPermissionRevokedByPolicy for user " + userId);
    }
    if (checkPermission(permission, packageName, userId)
            == PackageManager.PERMISSION_GRANTED) {
        return false;
    }
    final long identity = Binder.clearCallingIdentity();
    try {
        final int flags = getPermissionFlags(permission, packageName, userId);
        return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
    } finally {
        Binder.restoreCallingIdentity(identity);
    }
}

Потенциально, чтобы "подделать" статус определенного разрешения, вам нужно будет взломать методы checkPermission и getPermissionFlags. Проблема, я боюсь, что нет очевидного способа подачи приложения ApplicationPackageManager с избыточным пакетом PackageManagerService, по крайней мере, без отражения.

Ответ 2

Я не думаю, что есть прямой путь. Но, как работа, если время выполнения allowstate вызывающего пакета может быть изменено, тогда ispermissionrevokedbypolicy() вернет false. Но я чувствую, что это также будет сложной частью.