2.2 ApplicationInfo中的 privateFlags 和 PRIVATE_FLAG_PRIVILEGED
看一下ApplicationInfo源代码
/**
* Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
* {@hide}
*/
public int privateFlags;
/**
* Value for {@link #privateFlags}: set to {@code true} if the application
* is permitted to hold privileged permissions.
*
* {@hide}
*/
public static final int PRIVATE_FLAG_PRIVILEGED = 1<<3;
首先看到@hide,可见不会出现在Android公开API中,也就是说,第三方App无缘使用。先来看看这个字段在Android系统中是如何被使用的。随便找例子:
在系统应用安装器(PackageInstaller)中,packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
private boolean isInstallRequestFromUnknownSource(Intent intent) {
String callerPackage = getCallingPackage();
if (callerPackage != null && intent.getBooleanExtra(
Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)) {
try {
mSourceInfo = mPm.getApplicationInfo(callerPackage, 0);
if (mSourceInfo != null) {
if ((mSourceInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
!= 0) {
// Privileged apps are not considered an unknown source.
return false;
}
}
} catch (NameNotFoundException e) {
}
}
return true;
}
frameworks/base/services/core/java/com/android/server/firewall/SenderFilter.java
static boolean isPrivilegedApp(int callerUid, int callerPid) {
if (callerUid == Process.SYSTEM_UID || callerUid == 0 ||
callerPid == Process.myPid() || callerPid == 0) {
return true;
}
IPackageManager pm = AppGlobals.getPackageManager();
try {
return (pm.getPrivateFlagsForUid(callerUid) & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
!= 0;
} catch (RemoteException ex) {
Slog.e(IntentFirewall.TAG, "Remote exception while retrieving uid flags",
ex);
}
return false;
}
由上面这些代码实例基本可以了解这个字段的用法。下面在PMS扫描/安装应用的逻辑中找到处理这个字段的部分来分析。
我们知道,PMS是PackageManager的后台服务,先看看PMS侧是如何实现PackageManager.getApplicationInfo()。
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java:
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
// writer
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if