Android 异常解析
java.lang.SecurityException: Package xxxx is currently frozen!
- 抛出异常地点:
// frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override
public void checkPackageStartable(String packageName, int userId) {
final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
throw new SecurityException("Instant applications don't have access to this method");
}
final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
throw new SecurityException("Package " + packageName + " was not found!");
}
if (!ps.getInstalled(userId)) {
throw new SecurityException(
"Package " + packageName + " was not installed for user " + userId + "!");
}
if (mSafeMode && !ps.isSystem()) {
throw new SecurityException("Package " + packageName + " not a system app!");
}
//看这里🙂🙂🙂🙂🙂🙂
if (mFrozenPackages.contains(packageName)) {
throw new SecurityException("Package " + packageName + " is currently frozen!");
}
if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
throw new SecurityException("Package " + packageName + " is not encryption aware!");
}
}
}
- 原因分析
因为检测到这个启动的包是被记录在 mFrozenPackages 这个了集合里, 那这个mFrozenPackages 是怎么收录应用的呢?
这个冻结集合 mFrozenPackages 是在构造 PackageFreezer 对象时添加的,其中的 killReason 也从侧面告知是因为什么
原因被添加到冻结集合里的, 这个 killReason 通过 AMS里的forceStopPackageLocked()方法以以下两种方式打印
- “Force stopping " + packageName + " appid=” + appId + " user=" + userId + ": " + reason
- “Force stopping u” + userId + ": " + reason
// frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public PackageFreezer(String packageName, int userId, String killReason) {
synchronized (mLock) {
mPackageName = packageName;
mWeFroze = mFrozenPackages.add(mPackageName);
final PackageSetting ps = mSettings.mPackages.get(mPackageName);
if (ps != null) {
killApplication(ps.name, ps.appId, userId, killReason);
}
}
mCloseGuard.open("close");
}
//主动冻结应用
public PackageFreezer freezePackage(String packageName, String killReason) {
return freezePackage(packageName, UserHandle.USER_ALL, killReason);
}
//冻结功能封装
public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
return new PackageFreezer(packageName, userId, killReason);
}
//包加载时冻结
public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
String killReason) {
return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
}
//包加载时冻结
public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
String killReason) {
if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
return new PackageFreezer();
} else {
return freezePackage(packageName, userId, killReason);
}
}
//包删除时冻结
public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
String killReason) {
return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
}
//包删除时冻结
public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
String killReason) {
if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
return new PackageFreezer();
} else {
return freezePackage(packageName, userId, killReason);
}
}
主动调用 freezePackage() 的场景有以下几种:
- addForInitLI(Package, int, int, long, UserHandle)
try (PackageFreezer freezer = freezePackage(pkg.packageName,
- clearApplicationProfileData(String)
try (PackageFreezer freezer = freezePackage(packageName, “clearApplicationProfileData”)) {
- clearApplicationUserData(String, IPackageDataObserver, int)
try (PackageFreezer freezer = freezePackage(packageName,
- setEnabledSetting(String, String, int, int, int, String)
freezePackage(deletedPkg.packageName, “setEnabledSetting”)) {
freezePackage(deletedPkg.packageName, “setEnabledSetting”)) { - loadPrivatePackagesInner(VolumeInfo)
freezers.add(freezePackage(ps.name, “loadPrivatePackagesInner”));
- movePackageInternal(String, String, int, int, UserHandle)
freezer = freezePackage(packageName, “movePackageInternal”);