PackageManager lock reduction: Settings on-change

Bug: 161323622

Improve change detection in the Settings class.  Attributes used in
the snapshot are now watched.

Test: atest
 * FrameworksServicesTests:UserSystemPackageInstallerTest
 * FrameworksServicesTests:PackageManagerSettingsTests
 * FrameworksServicesTests:PackageManagerServiceTest
 * FrameworksServicesTests:AppsFilterTest
 * FrameworksServicesTests:PackageInstallerSessionTest
 * FrameworksServicesTests:ScanTests
 * FrameworksServicesTests:WatcherTest

Change-Id: Icc4a81900d2014e09cabbb2628702c6c20fc4da6
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index f2aaee2..2d41a687 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -115,12 +115,15 @@
 import com.android.server.pm.permission.LegacyPermissionState;
 import com.android.server.pm.permission.LegacyPermissionState.PermissionState;
 import com.android.server.utils.Snappable;
-import com.android.server.utils.Snapshots;
 import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.utils.Watchable;
 import com.android.server.utils.WatchableImpl;
+import com.android.server.utils.Watched;
+import com.android.server.utils.WatchedArrayList;
 import com.android.server.utils.WatchedArrayMap;
+import com.android.server.utils.WatchedArraySet;
 import com.android.server.utils.WatchedSparseArray;
+import com.android.server.utils.WatchedSparseIntArray;
 import com.android.server.utils.Watcher;
 
 import libcore.io.IoUtils;
@@ -350,6 +353,7 @@
     private final File mKernelMappingFilename;
 
     /** Map from package name to settings */
+    @Watched
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     final WatchedArrayMap<String, PackageSetting> mPackages = new WatchedArrayMap<>();
 
@@ -357,21 +361,29 @@
      * List of packages that were involved in installing other packages, i.e. are listed
      * in at least one app's InstallSource.
      */
-    private final ArraySet<String> mInstallerPackages = new ArraySet<>();
+    @Watched
+    private final WatchedArraySet<String> mInstallerPackages = new WatchedArraySet<>();
 
     /** Map from package name to appId and excluded userids */
-    private final ArrayMap<String, KernelPackageState> mKernelMapping = new ArrayMap<>();
+    @Watched
+    private final WatchedArrayMap<String, KernelPackageState> mKernelMapping =
+            new WatchedArrayMap<>();
 
     // List of replaced system applications
+    @Watched
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    final ArrayMap<String, PackageSetting> mDisabledSysPackages = new ArrayMap<>();
+    final WatchedArrayMap<String, PackageSetting> mDisabledSysPackages = new WatchedArrayMap<>();
 
     /** List of packages that are blocked for uninstall for specific users */
-    private final SparseArray<ArraySet<String>> mBlockUninstallPackages = new SparseArray<>();
+    @Watched
+    private final WatchedSparseArray<ArraySet<String>> mBlockUninstallPackages =
+            new WatchedSparseArray<>();
 
     // Set of restored intent-filter verification states
-    private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications =
-            new ArrayMap<String, IntentFilterVerificationInfo>();
+    @Watched
+    private final WatchedArrayMap<String, IntentFilterVerificationInfo>
+            mRestoredIntentFilterVerifications =
+            new WatchedArrayMap<String, IntentFilterVerificationInfo>();
 
     private static final class KernelPackageState {
         int appId;
@@ -381,7 +393,8 @@
     private static int mFirstAvailableUid = 0;
 
     /** Map from volume UUID to {@link VersionInfo} */
-    private ArrayMap<String, VersionInfo> mVersion = new ArrayMap<>();
+    @Watched
+    private WatchedArrayMap<String, VersionInfo> mVersion = new WatchedArrayMap<>();
 
     /**
      * Version details for a storage volume that may hold apps.
@@ -423,21 +436,27 @@
 
     // The user's preferred activities associated with particular intent
     // filters.
+    @Watched
     private final WatchedSparseArray<PreferredIntentResolver>
             mPreferredActivities = new WatchedSparseArray<>();
 
     // The persistent preferred activities of the user's profile/device owner
     // associated with particular intent filters.
+    @Watched
     private final WatchedSparseArray<PersistentPreferredIntentResolver>
             mPersistentPreferredActivities = new WatchedSparseArray<>();
 
     // For every user, it is used to find to which other users the intent can be forwarded.
+    @Watched
     private final WatchedSparseArray<CrossProfileIntentResolver>
             mCrossProfileIntentResolvers = new WatchedSparseArray<>();
 
-    final ArrayMap<String, SharedUserSetting> mSharedUsers = new ArrayMap<>();
-    private final ArrayList<SettingBase> mAppIds;
-    private final SparseArray<SettingBase> mOtherAppIds;
+    @Watched
+    final WatchedArrayMap<String, SharedUserSetting> mSharedUsers = new WatchedArrayMap<>();
+    @Watched
+    private final WatchedArrayList<SettingBase> mAppIds;
+    @Watched
+    private final WatchedSparseArray<SettingBase> mOtherAppIds;
 
     // For reading/writing settings file.
     private final ArrayList<Signature> mPastSignatures =
@@ -449,13 +468,17 @@
     // Keys are the new names of the packages, values are the original
     // names.  The packages appear everywhere else under their original
     // names.
-    private final ArrayMap<String, String> mRenamedPackages = new ArrayMap<String, String>();
+    @Watched
+    private final WatchedArrayMap<String, String> mRenamedPackages =
+            new WatchedArrayMap<String, String>();
 
     // For every user, it is used to find the package name of the default Browser App.
-    final SparseArray<String> mDefaultBrowserApp = new SparseArray<String>();
+    @Watched
+    final WatchedSparseArray<String> mDefaultBrowserApp = new WatchedSparseArray<String>();
 
     // App-link priority tracking, per-user
-    final SparseIntArray mNextAppLinkGeneration = new SparseIntArray();
+    @Watched
+    final WatchedSparseIntArray mNextAppLinkGeneration = new WatchedSparseIntArray();
 
     final StringBuilder mReadMessages = new StringBuilder();
 
@@ -492,8 +515,8 @@
     public Settings(Map<String, PackageSetting> pkgSettings) {
         mLock = new Object();
         mPackages.putAll(pkgSettings);
-        mAppIds = new ArrayList<>();
-        mOtherAppIds = new SparseArray<>();
+        mAppIds = new WatchedArrayList<>();
+        mOtherAppIds = new WatchedSparseArray<>();
         mSystemDir = null;
         mPermissions = null;
         mRuntimePermissionsPersistence = null;
@@ -504,17 +527,30 @@
         mStoppedPackagesFilename = null;
         mBackupStoppedPackagesFilename = null;
         mKernelMappingFilename = null;
+
         mPackages.registerObserver(mObserver);
+        mInstallerPackages.registerObserver(mObserver);
+        mKernelMapping.registerObserver(mObserver);
+        mDisabledSysPackages.registerObserver(mObserver);
+        mBlockUninstallPackages.registerObserver(mObserver);
+        mRestoredIntentFilterVerifications.registerObserver(mObserver);
+        mVersion.registerObserver(mObserver);
         mPreferredActivities.registerObserver(mObserver);
         mPersistentPreferredActivities.registerObserver(mObserver);
         mCrossProfileIntentResolvers.registerObserver(mObserver);
+        mSharedUsers.registerObserver(mObserver);
+        mAppIds.registerObserver(mObserver);
+        mOtherAppIds.registerObserver(mObserver);
+        mRenamedPackages.registerObserver(mObserver);
+        mDefaultBrowserApp.registerObserver(mObserver);
+        mNextAppLinkGeneration.registerObserver(mObserver);
     }
 
     Settings(File dataDir, RuntimePermissionsPersistence runtimePermissionsPersistence,
             LegacyPermissionDataProvider permissionDataProvider, Object lock) {
         mLock = lock;
-        mAppIds = new ArrayList<>();
-        mOtherAppIds = new SparseArray<>();
+        mAppIds = new WatchedArrayList<>();
+        mOtherAppIds = new WatchedSparseArray<>();
         mPermissions = new LegacyPermissionSettings(lock);
         mRuntimePermissionsPersistence = new RuntimePermissionPersistence(
                 runtimePermissionsPersistence);
@@ -537,10 +573,24 @@
         // Deprecated: Needed for migration
         mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
         mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
+
+
         mPackages.registerObserver(mObserver);
+        mInstallerPackages.registerObserver(mObserver);
+        mKernelMapping.registerObserver(mObserver);
+        mDisabledSysPackages.registerObserver(mObserver);
+        mBlockUninstallPackages.registerObserver(mObserver);
+        mRestoredIntentFilterVerifications.registerObserver(mObserver);
+        mVersion.registerObserver(mObserver);
         mPreferredActivities.registerObserver(mObserver);
         mPersistentPreferredActivities.registerObserver(mObserver);
         mCrossProfileIntentResolvers.registerObserver(mObserver);
+        mSharedUsers.registerObserver(mObserver);
+        mAppIds.registerObserver(mObserver);
+        mOtherAppIds.registerObserver(mObserver);
+        mRenamedPackages.registerObserver(mObserver);
+        mDefaultBrowserApp.registerObserver(mObserver);
+        mNextAppLinkGeneration.registerObserver(mObserver);
     }
 
     /**
@@ -568,7 +618,7 @@
         mInstallerPackages.addAll(r.mInstallerPackages);
         mKernelMapping.putAll(r.mKernelMapping);
         mDisabledSysPackages.putAll(r.mDisabledSysPackages);
-        Snapshots.copy(mBlockUninstallPackages, r.mBlockUninstallPackages);
+        mBlockUninstallPackages.snapshot(r.mBlockUninstallPackages);
         mRestoredIntentFilterVerifications.putAll(r.mRestoredIntentFilterVerifications);
         mVersion.putAll(r.mVersion);
         mVerifierDeviceIdentity = r.mVerifierDeviceIdentity;
@@ -579,13 +629,13 @@
         WatchedSparseArray.snapshot(
                 mCrossProfileIntentResolvers, r.mCrossProfileIntentResolvers);
         mSharedUsers.putAll(r.mSharedUsers);
-        mAppIds = new ArrayList<>(r.mAppIds);
-        mOtherAppIds = r.mOtherAppIds.clone();
+        mAppIds = r.mAppIds.snapshot();
+        mOtherAppIds = r.mOtherAppIds.snapshot();
         mPastSignatures.addAll(r.mPastSignatures);
         mKeySetRefs.putAll(r.mKeySetRefs);
-        mRenamedPackages.putAll(r.mRenamedPackages);
-        Snapshots.copy(mDefaultBrowserApp, r.mDefaultBrowserApp);
-        Snapshots.snapshot(mNextAppLinkGeneration, r.mNextAppLinkGeneration);
+        mRenamedPackages.snapshot(r.mRenamedPackages);
+        mDefaultBrowserApp.snapshot(r.mDefaultBrowserApp);
+        mNextAppLinkGeneration.snapshot(r.mNextAppLinkGeneration);
         // mReadMessages
         mPendingPackages.addAll(r.mPendingPackages);
         mSystemDir = null;