忽如一夜春风来,千树万树梨花开
时光如白驹过隙,寥寥草草,今年的冬天又要到来了,怀念火炉打边的日子——

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()方法以以下两种方式打印

  1. “Force stopping " + packageName + " appid=” + appId + " user=" + userId + ": " + reason
  2. “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() 的场景有以下几种:

  1. addForInitLI(Package, int, int, long, UserHandle)

    try (PackageFreezer freezer = freezePackage(pkg.packageName,

  2. clearApplicationProfileData(String)

    try (PackageFreezer freezer = freezePackage(packageName, “clearApplicationProfileData”)) {

  3. clearApplicationUserData(String, IPackageDataObserver, int)

    try (PackageFreezer freezer = freezePackage(packageName,

  4. setEnabledSetting(String, String, int, int, int, String)

    freezePackage(deletedPkg.packageName, “setEnabledSetting”)) {
    freezePackage(deletedPkg.packageName, “setEnabledSetting”)) {

  5. loadPrivatePackagesInner(VolumeInfo)

    freezers.add(freezePackage(ps.name, “loadPrivatePackagesInner”));

  6. movePackageInternal(String, String, int, int, UserHandle)

    freezer = freezePackage(packageName, “movePackageInternal”);

posted on 2020-10-23 15:01  寒风凛凛  阅读(1313)  评论(0编辑  收藏  举报