API级别23已添加 isPermissionRevokedByPolicy()
on PackageManager
。如果某个包“通过策略”被阻止了所请求的权限,则应该返回false
:
开发人员是否可以做一些事情,以使isPermissionRevokedByPolicy()
为某些打包/许可组合返回false
,而无需经历整个Android for Work的恶作剧集?
最佳答案
当然,我可能错了,但是不幸的是,简短的答案似乎是“不,没有”。
扩展一些的答案:
这是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;
}
(source code)
更深入地研究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;
}
(source code)
我为查找isPermissionRevokedByPolicy btw的实际实现所做的所有这些步骤。然后,我必须找到谁扩展了IPackageManager.Stub-它是PackageManagerService(source code)。
所以这是实际的实现:
@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方法。恐怕,问题是,至少在没有反射的情况下,没有明显的方法如何使用覆盖的PackageManagerService来填充ApplicationPackageManager。