diff options
| author | 2021-03-17 09:10:26 -0700 | |
|---|---|---|
| committer | 2021-03-17 10:53:23 -0700 | |
| commit | 362cec4a4592f78cf9092851da1093c0e7fb19ac (patch) | |
| tree | e1c1ec1e53f915d0a8299dc16219288b41af7aa9 | |
| parent | 6681a15237e0ea18135f249de371d51ca83b78b3 (diff) | |
Move PM cache invalidate inside mlock
Bug: 181992565
Ensure that the PM cache invalidation occurs inside regions protected
by the PM mlock. Recent changes guard the invalidation so that it
occurs only if something really changed - this limits the number of
invalidation calls and makes it lower overhead.
Create a new marker class for the PM lock, similar to the marker class
ActivityManagerGlobalLock. The marker class has no performance impact
but it enables future snapshot improvements using lock injection.
The result is tested with a special build that checks the snapshot
invalidation flag every time the PM lock is taken. The test verifies
that the invalidation flag is false (meaning the snapshot is valid)
every time the lock is taken, which means that invalidation occurs
only under control of mLock.
Test: atest
* FrameworksServicesTests:AppsFilterTest
* FrameworksServicesTests:PackageInstallerSessionTest
* FrameworksServicesTests:PackageManagerServiceTest
* FrameworksServicesTests:PackageManagerSettingsTests
* FrameworksServicesTests:ScanTests
* FrameworksServicesTests:UserSystemPackageInstallerTest
* PackageManagerServiceBootTest
* UserLifecycleTests#startUser
* UserLifecycleTests#stopUser
* UserLifecycleTests#switchUser
* android.appsecurity.cts.EphemeralTest
* android.appsecurity.cts.InstantAppUserTest
Change-Id: I96154fbee78b620c76a2b7d8614bc433fc61e911
5 files changed, 39 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index dfe72b26f72a..60d9eb58ccc2 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -882,7 +882,7 @@ public class PackageManagerService extends IPackageManager.Stub // Lock for global state used when modifying package state or settings. // Methods that must be called with this lock held have // the suffix "Locked". Some methods may use the legacy suffix "LP" - final Object mLock; + final PackageManagerTracedLock mLock; // Keys are String (package name), values are Package. @Watched @@ -1041,7 +1041,7 @@ public class PackageManagerService extends IPackageManager.Stub private final PackageAbiHelper mAbiHelper; private final Context mContext; - private final Object mLock; + private final PackageManagerTracedLock mLock; private final Installer mInstaller; private final Object mInstallLock; private final Handler mBackgroundHandler; @@ -1081,7 +1081,7 @@ public class PackageManagerService extends IPackageManager.Stub mDomainVerificationManagerInternalProducer; private final Singleton<Handler> mHandlerProducer; - Injector(Context context, Object lock, Installer installer, + Injector(Context context, PackageManagerTracedLock lock, Installer installer, Object installLock, PackageAbiHelper abiHelper, Handler backgroundHandler, List<ScanPartition> systemPartitions, @@ -1181,7 +1181,7 @@ public class PackageManagerService extends IPackageManager.Stub return mUserManagerProducer.get(this, mPackageManager); } - public Object getLock() { + public PackageManagerTracedLock getLock() { return mLock; } @@ -5959,7 +5959,7 @@ public class PackageManagerService extends IPackageManager.Stub final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing", Trace.TRACE_TAG_PACKAGE_MANAGER); t.traceBegin("create package manager"); - final Object lock = new Object(); + final PackageManagerTracedLock lock = new PackageManagerTracedLock(); final Object installLock = new Object(); HandlerThread backgroundThread = new HandlerThread("PackageManagerBg"); backgroundThread.start(); @@ -26884,11 +26884,12 @@ public class PackageManagerService extends IPackageManager.Stub outUpdatedPackageNames.add(targetPackageName); modified = true; } - } - if (modified) { - invalidatePackageInfoCache(); + if (modified) { + invalidatePackageInfoCache(); + } } + return true; } diff --git a/services/core/java/com/android/server/pm/PackageManagerTracedLock.java b/services/core/java/com/android/server/pm/PackageManagerTracedLock.java new file mode 100644 index 000000000000..e15e8a839a9a --- /dev/null +++ b/services/core/java/com/android/server/pm/PackageManagerTracedLock.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm; + +/** + * This is a unique class that is used as the PackageManager lock. It can be targeted for lock + * injection, similar to {@link ActivityManagerGlobalLock}. + */ +public class PackageManagerTracedLock { +} diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index ec7b451c6ec9..b51b8330f911 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -353,7 +353,7 @@ public final class Settings implements Watchable, Snappable { private static final String ATTR_DATABASE_VERSION = "databaseVersion"; private static final String ATTR_VALUE = "value"; - private final Object mLock; + private final PackageManagerTracedLock mLock; private final RuntimePermissionPersistence mRuntimePermissionsPersistence; @@ -525,7 +525,7 @@ public final class Settings implements Watchable, Snappable { @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) public Settings(Map<String, PackageSetting> pkgSettings) { - mLock = new Object(); + mLock = new PackageManagerTracedLock(); mPackages.putAll(pkgSettings); mAppIds = new WatchedArrayList<>(); mOtherAppIds = new WatchedSparseArray<>(); @@ -562,7 +562,7 @@ public final class Settings implements Watchable, Snappable { Settings(File dataDir, RuntimePermissionsPersistence runtimePermissionsPersistence, LegacyPermissionDataProvider permissionDataProvider, @NonNull DomainVerificationManagerInternal domainVerificationManager, - @NonNull Object lock) { + @NonNull PackageManagerTracedLock lock) { mLock = lock; mAppIds = new WatchedArrayList<>(); mOtherAppIds = new WatchedSparseArray<>(); diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt index e853fd341ae5..17c6b6fba861 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt @@ -163,7 +163,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) { /** Collection of mocks used for PackageManagerService tests. */ class Mocks { - val lock = Any() + val lock = PackageManagerTracedLock() val installLock = Any() val injector: PackageManagerService.Injector = mock() val systemWrapper: PackageManagerService.SystemWrapper = mock() diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index 59458e8df118..d63a4674a83d 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -59,10 +59,10 @@ import androidx.test.runner.AndroidJUnit4; import com.android.permission.persistence.RuntimePermissionsPersistence; import com.android.server.LocalServices; -import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; import com.android.server.pm.parsing.pkg.PackageImpl; import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.permission.LegacyPermissionDataProvider; +import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; import com.android.server.utils.WatchableTester; import com.google.common.truth.Truth; @@ -1197,7 +1197,7 @@ public class PackageManagerSettingsTests { private Settings makeSettings() { return new Settings(InstrumentationRegistry.getContext().getFilesDir(), mRuntimePermissionsPersistence, mPermissionDataProvider, - mDomainVerificationManager, new Object()); + mDomainVerificationManager, new PackageManagerTracedLock()); } private void verifyKeySetMetaData(Settings settings) |