普通开发者如何试用isPermissionRevokedByPolicy()?
How Do Ordinary Developers Try Out isPermissionRevokedByPolicy()?
API 已添加 23 级 isPermissionRevokedByPolicy()
on PackageManager
。它应该 return false
如果某个包的请求权限被阻止 "by policy":
Typically the device owner or the profile owner may apply such a policy.
对于某些 package/permission 组合,开发人员可以做些什么来使 isPermissionRevokedByPolicy()
到 return false
,而不是遍历整个 Android 对于恶作剧的工作集?
当然,我可能是错的,但不幸的是,看起来简短的答案是 "no, there's not"。
更详细的回答:
这是 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 顺便说一句的实际实现。然后我必须找到谁扩展了 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);
}
}
可能 "fake" 特定权限的状态,您需要修改 checkPermission 和 getPermissionFlags 方法。恐怕问题是,没有明显的方法可以为 ApplicationPackageManager 提供覆盖的 PackageManagerService,至少,没有反射。
我认为没有直接的方法。但是如果调用包的运行时 permissionstate 可以更改,那么 ispermissionrevokedbypolicy() 将 return 为 false。但我觉得这也是一个棘手的部分。
API 已添加 23 级 isPermissionRevokedByPolicy()
on PackageManager
。它应该 return false
如果某个包的请求权限被阻止 "by policy":
Typically the device owner or the profile owner may apply such a policy.
对于某些 package/permission 组合,开发人员可以做些什么来使 isPermissionRevokedByPolicy()
到 return false
,而不是遍历整个 Android 对于恶作剧的工作集?
当然,我可能是错的,但不幸的是,看起来简短的答案是 "no, there's not"。
更详细的回答: 这是 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 顺便说一句的实际实现。然后我必须找到谁扩展了 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);
}
}
可能 "fake" 特定权限的状态,您需要修改 checkPermission 和 getPermissionFlags 方法。恐怕问题是,没有明显的方法可以为 ApplicationPackageManager 提供覆盖的 PackageManagerService,至少,没有反射。
我认为没有直接的方法。但是如果调用包的运行时 permissionstate 可以更改,那么 ispermissionrevokedbypolicy() 将 return 为 false。但我觉得这也是一个棘手的部分。