Loading services/core/java/com/android/server/pm/PackageManagerService.java +17 −18 Original line number Diff line number Diff line Loading @@ -5940,6 +5940,21 @@ public class PackageManagerService extends IPackageManager.Stub } } // Link watchables to the class private void registerObserver() { mPackages.registerObserver(mWatcher); mSharedLibraries.registerObserver(mWatcher); mStaticLibsByDeclaringPackage.registerObserver(mWatcher); mInstrumentation.registerObserver(mWatcher); mWebInstantAppsDisabled.registerObserver(mWatcher); mAppsFilter.registerObserver(mWatcher); mInstantAppRegistry.registerObserver(mWatcher); mSettings.registerObserver(mWatcher); // If neither "build" attribute is true then this may be a mockito test, and verification // can fail as a false positive. Watchable.verifyWatchedAttributes(this, mWatcher, !(mIsEngBuild || mIsUserDebugBuild)); } /** * A extremely minimal constructor designed to start up a PackageManagerService instance for * testing. Loading Loading @@ -6023,15 +6038,7 @@ public class PackageManagerService extends IPackageManager.Stub sSnapshotCorked = true; mLiveComputer = createLiveComputer(); mSnapshotComputer = mLiveComputer; // Link up the watchers mPackages.registerObserver(mWatcher); mSharedLibraries.registerObserver(mWatcher); mStaticLibsByDeclaringPackage.registerObserver(mWatcher); mInstrumentation.registerObserver(mWatcher); mWebInstantAppsDisabled.registerObserver(mWatcher); mAppsFilter.registerObserver(mWatcher); Watchable.verifyWatchedAttributes(this, mWatcher); registerObserver(); mPackages.putAll(testParams.packages); mEnableFreeCacheV2 = testParams.enableFreeCacheV2; Loading Loading @@ -6185,15 +6192,6 @@ public class PackageManagerService extends IPackageManager.Stub mDomainVerificationManager = injector.getDomainVerificationManagerInternal(); mDomainVerificationManager.setConnection(mDomainVerificationConnection); // Link up the watchers mPackages.registerObserver(mWatcher); mSharedLibraries.registerObserver(mWatcher); mStaticLibsByDeclaringPackage.registerObserver(mWatcher); mInstrumentation.registerObserver(mWatcher); mWebInstantAppsDisabled.registerObserver(mWatcher); mAppsFilter.registerObserver(mWatcher); Watchable.verifyWatchedAttributes(this, mWatcher); // Create the computer as soon as the state objects have been installed. The // cached computer is the same as the live computer until the end of the // constructor, at which time the invalidation method updates it. The cache is Loading @@ -6202,6 +6200,7 @@ public class PackageManagerService extends IPackageManager.Stub sSnapshotCorked = true; mLiveComputer = createLiveComputer(); mSnapshotComputer = mLiveComputer; registerObserver(); // CHECKSTYLE:OFF IndentationCheck synchronized (mInstallLock) { services/core/java/com/android/server/pm/Settings.java +7 −4 Original line number Diff line number Diff line Loading @@ -107,9 +107,6 @@ import com.android.permission.persistence.RuntimePermissionsState; import com.android.server.LocalServices; import com.android.server.backup.PreferredActivityBackupHelper; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.verify.domain.DomainVerificationLegacySettings; import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; import com.android.server.pm.verify.domain.DomainVerificationPersistence; import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; Loading @@ -117,6 +114,9 @@ import com.android.server.pm.permission.LegacyPermissionDataProvider; import com.android.server.pm.permission.LegacyPermissionSettings; import com.android.server.pm.permission.LegacyPermissionState; import com.android.server.pm.permission.LegacyPermissionState.PermissionState; import com.android.server.pm.verify.domain.DomainVerificationLegacySettings; import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; import com.android.server.pm.verify.domain.DomainVerificationPersistence; import com.android.server.utils.Snappable; import com.android.server.utils.TimingsTraceAndSlog; import com.android.server.utils.Watchable; Loading Loading @@ -489,7 +489,7 @@ public final class Settings implements Watchable, Snappable { // App-link priority tracking, per-user @NonNull @Watched final WatchedSparseIntArray mNextAppLinkGeneration = new WatchedSparseIntArray(); private final WatchedSparseIntArray mNextAppLinkGeneration = new WatchedSparseIntArray(); final StringBuilder mReadMessages = new StringBuilder(); Loading Loading @@ -554,6 +554,7 @@ public final class Settings implements Watchable, Snappable { mAppIds.registerObserver(mObserver); mOtherAppIds.registerObserver(mObserver); mRenamedPackages.registerObserver(mObserver); mNextAppLinkGeneration.registerObserver(mObserver); mDefaultBrowserApp.registerObserver(mObserver); Watchable.verifyWatchedAttributes(this, mObserver); Loading Loading @@ -604,6 +605,7 @@ public final class Settings implements Watchable, Snappable { mAppIds.registerObserver(mObserver); mOtherAppIds.registerObserver(mObserver); mRenamedPackages.registerObserver(mObserver); mNextAppLinkGeneration.registerObserver(mObserver); mDefaultBrowserApp.registerObserver(mObserver); Watchable.verifyWatchedAttributes(this, mObserver); Loading Loading @@ -651,6 +653,7 @@ public final class Settings implements Watchable, Snappable { mPastSignatures.addAll(r.mPastSignatures); mKeySetRefs.putAll(r.mKeySetRefs); mRenamedPackages.snapshot(r.mRenamedPackages); mNextAppLinkGeneration.snapshot(r.mNextAppLinkGeneration); mDefaultBrowserApp.snapshot(r.mDefaultBrowserApp); // mReadMessages mPendingPackages.addAll(r.mPendingPackages); Loading services/core/java/com/android/server/utils/Watchable.java +35 −21 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ package com.android.server.utils; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Build; import android.util.Log; import java.lang.annotation.Annotation; import java.lang.reflect.Field; /** Loading Loading @@ -60,41 +60,55 @@ public interface Watchable { */ public void dispatchChange(@Nullable Watchable what); /** * Return true if the field is tagged with @Watched */ private static boolean isWatched(Field f) { for (Annotation a : f.getDeclaredAnnotations()) { if (a.annotationType().equals(Watched.class)) { return true; } } return false; } /** * Verify that all @Watched {@link Watchable} attributes are being watched by this * class. This requires reflection and only runs in engineering or user debug * builds. * @param base The object that contains watched attributes. * @param observer The {@link Watcher} that should be watching these attributes. * @param logOnly If true then log errors; if false then throw an RuntimeExecption on error. */ static void verifyWatchedAttributes(Object base, Watcher observer) { if (Build.IS_ENG || Build.IS_USERDEBUG) { static void verifyWatchedAttributes(Object base, Watcher observer, boolean logOnly) { if (!(Build.IS_ENG || Build.IS_USERDEBUG)) { return; } for (Field f : base.getClass().getDeclaredFields()) { if (f.getAnnotation(Watched.class) != null) { final String fn = base.getClass().getName() + "." + f.getName(); try { final boolean flagged = isWatched(f); f.setAccessible(true); final Object o = f.get(base); final boolean watchable = o instanceof Watchable; if (flagged && watchable) { Watchable attr = (Watchable) f.get(base); if (o instanceof Watchable) { Watchable attr = (Watchable) (o); if (attr != null && !attr.isRegisteredObserver(observer)) { throw new RuntimeException(f.getName() + " missing an observer"); if (logOnly) { Log.e("Watchable", fn + " missing an observer"); } else { throw new RuntimeException("Watchable " + fn + " missing an observer"); } } } } catch (IllegalAccessException e) { // The field is protected; ignore it. Other exceptions that may be thrown by // Field.get() are allowed to roll up. if (logOnly) { Log.e("Watchable", fn + " not visible"); } else { throw new RuntimeException("Watchable " + fn + " not visible"); } } } } } /** * Verify that all @Watched {@link Watchable} attributes are being watched by this * class. This calls verifyWatchedAttributes() with logOnly set to false. * @param base The object that contains watched attributes. * @param observer The {@link Watcher} that should be watching these attributes. */ static void verifyWatchedAttributes(Object base, Watcher observer) { verifyWatchedAttributes(base, observer, false); } } Loading
services/core/java/com/android/server/pm/PackageManagerService.java +17 −18 Original line number Diff line number Diff line Loading @@ -5940,6 +5940,21 @@ public class PackageManagerService extends IPackageManager.Stub } } // Link watchables to the class private void registerObserver() { mPackages.registerObserver(mWatcher); mSharedLibraries.registerObserver(mWatcher); mStaticLibsByDeclaringPackage.registerObserver(mWatcher); mInstrumentation.registerObserver(mWatcher); mWebInstantAppsDisabled.registerObserver(mWatcher); mAppsFilter.registerObserver(mWatcher); mInstantAppRegistry.registerObserver(mWatcher); mSettings.registerObserver(mWatcher); // If neither "build" attribute is true then this may be a mockito test, and verification // can fail as a false positive. Watchable.verifyWatchedAttributes(this, mWatcher, !(mIsEngBuild || mIsUserDebugBuild)); } /** * A extremely minimal constructor designed to start up a PackageManagerService instance for * testing. Loading Loading @@ -6023,15 +6038,7 @@ public class PackageManagerService extends IPackageManager.Stub sSnapshotCorked = true; mLiveComputer = createLiveComputer(); mSnapshotComputer = mLiveComputer; // Link up the watchers mPackages.registerObserver(mWatcher); mSharedLibraries.registerObserver(mWatcher); mStaticLibsByDeclaringPackage.registerObserver(mWatcher); mInstrumentation.registerObserver(mWatcher); mWebInstantAppsDisabled.registerObserver(mWatcher); mAppsFilter.registerObserver(mWatcher); Watchable.verifyWatchedAttributes(this, mWatcher); registerObserver(); mPackages.putAll(testParams.packages); mEnableFreeCacheV2 = testParams.enableFreeCacheV2; Loading Loading @@ -6185,15 +6192,6 @@ public class PackageManagerService extends IPackageManager.Stub mDomainVerificationManager = injector.getDomainVerificationManagerInternal(); mDomainVerificationManager.setConnection(mDomainVerificationConnection); // Link up the watchers mPackages.registerObserver(mWatcher); mSharedLibraries.registerObserver(mWatcher); mStaticLibsByDeclaringPackage.registerObserver(mWatcher); mInstrumentation.registerObserver(mWatcher); mWebInstantAppsDisabled.registerObserver(mWatcher); mAppsFilter.registerObserver(mWatcher); Watchable.verifyWatchedAttributes(this, mWatcher); // Create the computer as soon as the state objects have been installed. The // cached computer is the same as the live computer until the end of the // constructor, at which time the invalidation method updates it. The cache is Loading @@ -6202,6 +6200,7 @@ public class PackageManagerService extends IPackageManager.Stub sSnapshotCorked = true; mLiveComputer = createLiveComputer(); mSnapshotComputer = mLiveComputer; registerObserver(); // CHECKSTYLE:OFF IndentationCheck synchronized (mInstallLock) {
services/core/java/com/android/server/pm/Settings.java +7 −4 Original line number Diff line number Diff line Loading @@ -107,9 +107,6 @@ import com.android.permission.persistence.RuntimePermissionsState; import com.android.server.LocalServices; import com.android.server.backup.PreferredActivityBackupHelper; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.verify.domain.DomainVerificationLegacySettings; import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; import com.android.server.pm.verify.domain.DomainVerificationPersistence; import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; Loading @@ -117,6 +114,9 @@ import com.android.server.pm.permission.LegacyPermissionDataProvider; import com.android.server.pm.permission.LegacyPermissionSettings; import com.android.server.pm.permission.LegacyPermissionState; import com.android.server.pm.permission.LegacyPermissionState.PermissionState; import com.android.server.pm.verify.domain.DomainVerificationLegacySettings; import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; import com.android.server.pm.verify.domain.DomainVerificationPersistence; import com.android.server.utils.Snappable; import com.android.server.utils.TimingsTraceAndSlog; import com.android.server.utils.Watchable; Loading Loading @@ -489,7 +489,7 @@ public final class Settings implements Watchable, Snappable { // App-link priority tracking, per-user @NonNull @Watched final WatchedSparseIntArray mNextAppLinkGeneration = new WatchedSparseIntArray(); private final WatchedSparseIntArray mNextAppLinkGeneration = new WatchedSparseIntArray(); final StringBuilder mReadMessages = new StringBuilder(); Loading Loading @@ -554,6 +554,7 @@ public final class Settings implements Watchable, Snappable { mAppIds.registerObserver(mObserver); mOtherAppIds.registerObserver(mObserver); mRenamedPackages.registerObserver(mObserver); mNextAppLinkGeneration.registerObserver(mObserver); mDefaultBrowserApp.registerObserver(mObserver); Watchable.verifyWatchedAttributes(this, mObserver); Loading Loading @@ -604,6 +605,7 @@ public final class Settings implements Watchable, Snappable { mAppIds.registerObserver(mObserver); mOtherAppIds.registerObserver(mObserver); mRenamedPackages.registerObserver(mObserver); mNextAppLinkGeneration.registerObserver(mObserver); mDefaultBrowserApp.registerObserver(mObserver); Watchable.verifyWatchedAttributes(this, mObserver); Loading Loading @@ -651,6 +653,7 @@ public final class Settings implements Watchable, Snappable { mPastSignatures.addAll(r.mPastSignatures); mKeySetRefs.putAll(r.mKeySetRefs); mRenamedPackages.snapshot(r.mRenamedPackages); mNextAppLinkGeneration.snapshot(r.mNextAppLinkGeneration); mDefaultBrowserApp.snapshot(r.mDefaultBrowserApp); // mReadMessages mPendingPackages.addAll(r.mPendingPackages); Loading
services/core/java/com/android/server/utils/Watchable.java +35 −21 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ package com.android.server.utils; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Build; import android.util.Log; import java.lang.annotation.Annotation; import java.lang.reflect.Field; /** Loading Loading @@ -60,41 +60,55 @@ public interface Watchable { */ public void dispatchChange(@Nullable Watchable what); /** * Return true if the field is tagged with @Watched */ private static boolean isWatched(Field f) { for (Annotation a : f.getDeclaredAnnotations()) { if (a.annotationType().equals(Watched.class)) { return true; } } return false; } /** * Verify that all @Watched {@link Watchable} attributes are being watched by this * class. This requires reflection and only runs in engineering or user debug * builds. * @param base The object that contains watched attributes. * @param observer The {@link Watcher} that should be watching these attributes. * @param logOnly If true then log errors; if false then throw an RuntimeExecption on error. */ static void verifyWatchedAttributes(Object base, Watcher observer) { if (Build.IS_ENG || Build.IS_USERDEBUG) { static void verifyWatchedAttributes(Object base, Watcher observer, boolean logOnly) { if (!(Build.IS_ENG || Build.IS_USERDEBUG)) { return; } for (Field f : base.getClass().getDeclaredFields()) { if (f.getAnnotation(Watched.class) != null) { final String fn = base.getClass().getName() + "." + f.getName(); try { final boolean flagged = isWatched(f); f.setAccessible(true); final Object o = f.get(base); final boolean watchable = o instanceof Watchable; if (flagged && watchable) { Watchable attr = (Watchable) f.get(base); if (o instanceof Watchable) { Watchable attr = (Watchable) (o); if (attr != null && !attr.isRegisteredObserver(observer)) { throw new RuntimeException(f.getName() + " missing an observer"); if (logOnly) { Log.e("Watchable", fn + " missing an observer"); } else { throw new RuntimeException("Watchable " + fn + " missing an observer"); } } } } catch (IllegalAccessException e) { // The field is protected; ignore it. Other exceptions that may be thrown by // Field.get() are allowed to roll up. if (logOnly) { Log.e("Watchable", fn + " not visible"); } else { throw new RuntimeException("Watchable " + fn + " not visible"); } } } } } /** * Verify that all @Watched {@link Watchable} attributes are being watched by this * class. This calls verifyWatchedAttributes() with logOnly set to false. * @param base The object that contains watched attributes. * @param observer The {@link Watcher} that should be watching these attributes. */ static void verifyWatchedAttributes(Object base, Watcher observer) { verifyWatchedAttributes(base, observer, false); } }