Merge "Remove PMS snapshot lambdas" into tm-dev
This commit is contained in:
@@ -67,7 +67,7 @@ import java.util.function.Consumer;
|
|||||||
*
|
*
|
||||||
* @hide Only for use within the system server.
|
* @hide Only for use within the system server.
|
||||||
*/
|
*/
|
||||||
public abstract class PackageManagerInternal implements PackageSettingsSnapshotProvider {
|
public abstract class PackageManagerInternal {
|
||||||
@IntDef(prefix = "PACKAGE_", value = {
|
@IntDef(prefix = "PACKAGE_", value = {
|
||||||
PACKAGE_SYSTEM,
|
PACKAGE_SYSTEM,
|
||||||
PACKAGE_SETUP_WIZARD,
|
PACKAGE_SETUP_WIZARD,
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 android.content.pm;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.android.internal.util.FunctionalUtils;
|
|
||||||
import com.android.server.pm.PackageManagerService;
|
|
||||||
import com.android.server.pm.PackageSetting;
|
|
||||||
import com.android.server.pm.pkg.PackageStateInternal;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
public interface PackageSettingsSnapshotProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run a function block that requires access to {@link PackageStateInternal} data. This will
|
|
||||||
* ensure the {@link PackageManagerService} lock is taken before any caller's internal lock
|
|
||||||
* to avoid deadlock. Note that this method may or may not lock. If a snapshot is available
|
|
||||||
* and valid, it will iterate the snapshot set of data.
|
|
||||||
*/
|
|
||||||
void withPackageSettingsSnapshot(
|
|
||||||
@NonNull Consumer<Function<String, PackageStateInternal>> block);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variant which returns a value to the caller.
|
|
||||||
* @see #withPackageSettingsSnapshot(Consumer)
|
|
||||||
*/
|
|
||||||
<Output> Output withPackageSettingsSnapshotReturning(
|
|
||||||
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageStateInternal>,
|
|
||||||
Output> block);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variant which throws.
|
|
||||||
* @see #withPackageSettingsSnapshot(Consumer)
|
|
||||||
*/
|
|
||||||
<ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
|
|
||||||
@NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageStateInternal>,
|
|
||||||
ExceptionType> block) throws ExceptionType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variant which throws 2 exceptions.
|
|
||||||
* @see #withPackageSettingsSnapshot(Consumer)
|
|
||||||
*/
|
|
||||||
<ExceptionOne extends Exception, ExceptionTwo extends Exception> void
|
|
||||||
withPackageSettingsSnapshotThrowing2(
|
|
||||||
@NonNull FunctionalUtils.ThrowingChecked2Consumer<
|
|
||||||
Function<String, PackageStateInternal>,
|
|
||||||
ExceptionOne, ExceptionTwo> block)
|
|
||||||
throws ExceptionOne, ExceptionTwo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variant which returns a value to the caller and throws.
|
|
||||||
* @see #withPackageSettingsSnapshot(Consumer)
|
|
||||||
*/
|
|
||||||
<Output, ExceptionType extends Exception> Output
|
|
||||||
withPackageSettingsSnapshotReturningThrowing(
|
|
||||||
@NonNull FunctionalUtils.ThrowingCheckedFunction<
|
|
||||||
Function<String, PackageStateInternal>, Output, ExceptionType> block)
|
|
||||||
throws ExceptionType;
|
|
||||||
}
|
|
||||||
@@ -3134,8 +3134,8 @@ public class ComputerEngine implements Computer {
|
|||||||
writer.println("Domain verification status:");
|
writer.println("Domain verification status:");
|
||||||
writer.increaseIndent();
|
writer.increaseIndent();
|
||||||
try {
|
try {
|
||||||
mDomainVerificationManager.printState(writer, packageName,
|
mDomainVerificationManager.printState(this, writer, packageName,
|
||||||
UserHandle.USER_ALL, mSettings::getPackage);
|
UserHandle.USER_ALL);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
pw.println("Failure printing domain verification information");
|
pw.println("Failure printing domain verification information");
|
||||||
Slog.e(TAG, "Failure printing domain verification information", e);
|
Slog.e(TAG, "Failure printing domain verification information", e);
|
||||||
|
|||||||
@@ -453,7 +453,8 @@ final class DeletePackageHelper {
|
|||||||
}
|
}
|
||||||
for (final int affectedUserId : affectedUserIds) {
|
for (final int affectedUserId : affectedUserIds) {
|
||||||
if (hadSuspendAppsPermission.get(affectedUserId)) {
|
if (hadSuspendAppsPermission.get(affectedUserId)) {
|
||||||
mPm.unsuspendForSuspendingPackage(packageName, affectedUserId);
|
mPm.unsuspendForSuspendingPackage(mPm.snapshotComputer(), packageName,
|
||||||
|
affectedUserId);
|
||||||
mPm.removeAllDistractingPackageRestrictions(affectedUserId);
|
mPm.removeAllDistractingPackageRestrictions(affectedUserId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,17 +26,12 @@ import android.os.Binder;
|
|||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
|
||||||
import com.android.internal.util.FunctionalUtils;
|
|
||||||
import com.android.server.DeviceIdleInternal;
|
import com.android.server.DeviceIdleInternal;
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
||||||
import com.android.server.pm.pkg.PackageStateInternal;
|
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationService;
|
import com.android.server.pm.verify.domain.DomainVerificationService;
|
||||||
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV1;
|
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV1;
|
||||||
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV2;
|
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV2;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public final class DomainVerificationConnection implements DomainVerificationService.Connection,
|
public final class DomainVerificationConnection implements DomainVerificationService.Connection,
|
||||||
DomainVerificationProxyV1.Connection, DomainVerificationProxyV2.Connection {
|
DomainVerificationProxyV1.Connection, DomainVerificationProxyV2.Connection {
|
||||||
final PackageManagerService mPm;
|
final PackageManagerService mPm;
|
||||||
@@ -111,42 +106,8 @@ public final class DomainVerificationConnection implements DomainVerificationSer
|
|||||||
return mUmInternal.exists(userId);
|
return mUmInternal.exists(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@NonNull
|
||||||
public void withPackageSettingsSnapshot(
|
public Computer snapshot() {
|
||||||
@NonNull Consumer<Function<String, PackageStateInternal>> block) {
|
return (Computer) mPmInternal.snapshot();
|
||||||
mPmInternal.withPackageSettingsSnapshot(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <Output> Output withPackageSettingsSnapshotReturning(
|
|
||||||
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageStateInternal>,
|
|
||||||
Output> block) {
|
|
||||||
return mPmInternal.withPackageSettingsSnapshotReturning(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
|
|
||||||
@NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageStateInternal>,
|
|
||||||
ExceptionType> block) throws ExceptionType {
|
|
||||||
mPmInternal.withPackageSettingsSnapshotThrowing(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
|
|
||||||
withPackageSettingsSnapshotThrowing2(
|
|
||||||
@NonNull FunctionalUtils.ThrowingChecked2Consumer<
|
|
||||||
Function<String, PackageStateInternal>, ExceptionOne,
|
|
||||||
ExceptionTwo> block)
|
|
||||||
throws ExceptionOne, ExceptionTwo {
|
|
||||||
mPmInternal.withPackageSettingsSnapshotThrowing2(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <Output, ExceptionType extends Exception> Output
|
|
||||||
withPackageSettingsSnapshotReturningThrowing(
|
|
||||||
@NonNull FunctionalUtils.ThrowingCheckedFunction<
|
|
||||||
Function<String, PackageStateInternal>, Output, ExceptionType> block)
|
|
||||||
throws ExceptionType {
|
|
||||||
return mPmInternal.withPackageSettingsSnapshotReturningThrowing(block);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
|
|||||||
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
|
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
|
||||||
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
|
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
|
||||||
import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
|
import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
|
||||||
import static android.content.pm.PackageManagerInternal.PACKAGE_SETUP_WIZARD;
|
|
||||||
import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
|
import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
|
||||||
import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile;
|
import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile;
|
||||||
import static android.os.PowerExemptionManager.REASON_PACKAGE_REPLACED;
|
import static android.os.PowerExemptionManager.REASON_PACKAGE_REPLACED;
|
||||||
@@ -145,6 +144,7 @@ import com.android.internal.content.F2fsUtils;
|
|||||||
import com.android.internal.content.InstallLocationUtils;
|
import com.android.internal.content.InstallLocationUtils;
|
||||||
import com.android.internal.security.VerityUtils;
|
import com.android.internal.security.VerityUtils;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
|
import com.android.internal.util.CollectionUtils;
|
||||||
import com.android.internal.util.FrameworkStatsLog;
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
import com.android.server.EventLogTags;
|
import com.android.server.EventLogTags;
|
||||||
import com.android.server.pm.dex.ArtManagerService;
|
import com.android.server.pm.dex.ArtManagerService;
|
||||||
@@ -2563,7 +2563,9 @@ final class InstallPackageHelper {
|
|||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
||||||
|
|
||||||
synchronized (mPm.mLock) {
|
synchronized (mPm.mLock) {
|
||||||
size = mPm.mPendingBroadcasts.size();
|
final SparseArray<ArrayMap<String, ArrayList<String>>> userIdToPackagesToComponents =
|
||||||
|
mPm.mPendingBroadcasts.copiedMap();
|
||||||
|
size = userIdToPackagesToComponents.size();
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
// Nothing to be done. Just return
|
// Nothing to be done. Just return
|
||||||
return;
|
return;
|
||||||
@@ -2573,11 +2575,11 @@ final class InstallPackageHelper {
|
|||||||
uids = new int[size];
|
uids = new int[size];
|
||||||
int i = 0; // filling out the above arrays
|
int i = 0; // filling out the above arrays
|
||||||
|
|
||||||
for (int n = 0; n < mPm.mPendingBroadcasts.userIdCount(); n++) {
|
for (int n = 0; n < size; n++) {
|
||||||
final int packageUserId = mPm.mPendingBroadcasts.userIdAt(n);
|
final int packageUserId = userIdToPackagesToComponents.keyAt(n);
|
||||||
final ArrayMap<String, ArrayList<String>> componentsToBroadcast =
|
final ArrayMap<String, ArrayList<String>> componentsToBroadcast =
|
||||||
mPm.mPendingBroadcasts.packagesForUserId(packageUserId);
|
userIdToPackagesToComponents.valueAt(n);
|
||||||
final int numComponents = componentsToBroadcast.size();
|
final int numComponents = CollectionUtils.size(componentsToBroadcast);
|
||||||
for (int index = 0; i < size && index < numComponents; index++) {
|
for (int index = 0; i < size && index < numComponents; index++) {
|
||||||
packages[i] = componentsToBroadcast.keyAt(index);
|
packages[i] = componentsToBroadcast.keyAt(index);
|
||||||
components[i] = componentsToBroadcast.valueAt(index);
|
components[i] = componentsToBroadcast.valueAt(index);
|
||||||
|
|||||||
@@ -382,6 +382,7 @@ final class PackageHandler extends Handler {
|
|||||||
case PRUNE_UNUSED_STATIC_SHARED_LIBRARIES: {
|
case PRUNE_UNUSED_STATIC_SHARED_LIBRARIES: {
|
||||||
try {
|
try {
|
||||||
mPm.mInjector.getSharedLibrariesImpl().pruneUnusedStaticSharedLibraries(
|
mPm.mInjector.getSharedLibrariesImpl().pruneUnusedStaticSharedLibraries(
|
||||||
|
mPm.snapshotComputer(),
|
||||||
Long.MAX_VALUE,
|
Long.MAX_VALUE,
|
||||||
Settings.Global.getLong(mPm.mContext.getContentResolver(),
|
Settings.Global.getLong(mPm.mContext.getContentResolver(),
|
||||||
Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
|
Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
|
||||||
|
|||||||
@@ -293,7 +293,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of all those APKs everywhere.
|
* Keep track of all those APKs everywhere.
|
||||||
@@ -1898,7 +1897,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
t.traceEnd();
|
t.traceEnd();
|
||||||
|
|
||||||
t.traceBegin("read user settings");
|
t.traceBegin("read user settings");
|
||||||
mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(
|
mFirstBoot = !mSettings.readLPw(mLiveComputer,
|
||||||
|
mInjector.getUserManagerInternal().getUsers(
|
||||||
/* excludePartial= */ true,
|
/* excludePartial= */ true,
|
||||||
/* excludeDying= */ false,
|
/* excludeDying= */ false,
|
||||||
/* excludePreCreated= */ false));
|
/* excludePreCreated= */ false));
|
||||||
@@ -2841,8 +2841,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
if (file.getUsableSpace() >= bytes) return;
|
if (file.getUsableSpace() >= bytes) return;
|
||||||
|
|
||||||
|
Computer computer = snapshotComputer();
|
||||||
// 5. Consider shared libraries with refcount=0 and age>min cache period
|
// 5. Consider shared libraries with refcount=0 and age>min cache period
|
||||||
if (internalVolume && mSharedLibraries.pruneUnusedStaticSharedLibraries(bytes,
|
if (internalVolume && mSharedLibraries.pruneUnusedStaticSharedLibraries(computer, bytes,
|
||||||
android.provider.Settings.Global.getLong(mContext.getContentResolver(),
|
android.provider.Settings.Global.getLong(mContext.getContentResolver(),
|
||||||
Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
|
Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
|
||||||
FREE_STORAGE_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
|
FREE_STORAGE_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
|
||||||
@@ -2854,14 +2855,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
// 7. Consider installed instant apps unused longer than min cache period
|
// 7. Consider installed instant apps unused longer than min cache period
|
||||||
if (internalVolume) {
|
if (internalVolume) {
|
||||||
if (executeWithConsistentComputerReturning(computer ->
|
if (mInstantAppRegistry.pruneInstalledInstantApps(computer, bytes,
|
||||||
mInstantAppRegistry.pruneInstalledInstantApps(computer, bytes,
|
android.provider.Settings.Global.getLong(
|
||||||
android.provider.Settings.Global.getLong(
|
mContext.getContentResolver(),
|
||||||
mContext.getContentResolver(),
|
Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
||||||
Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
InstantAppRegistry
|
||||||
InstantAppRegistry
|
.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
|
||||||
.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD)))
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2881,14 +2880,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
// 10. Consider instant meta-data (uninstalled apps) older that min cache period
|
// 10. Consider instant meta-data (uninstalled apps) older that min cache period
|
||||||
if (internalVolume) {
|
if (internalVolume) {
|
||||||
if (executeWithConsistentComputerReturning(computer ->
|
if (mInstantAppRegistry.pruneUninstalledInstantApps(computer, bytes,
|
||||||
mInstantAppRegistry.pruneUninstalledInstantApps(computer, bytes,
|
android.provider.Settings.Global.getLong(
|
||||||
android.provider.Settings.Global.getLong(
|
mContext.getContentResolver(),
|
||||||
mContext.getContentResolver(),
|
Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
||||||
Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
InstantAppRegistry
|
||||||
InstantAppRegistry
|
.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
|
||||||
.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD)))
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3493,8 +3490,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
|
enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
|
||||||
false /* checkShell */, "getEphemeralApplications");
|
false /* checkShell */, "getEphemeralApplications");
|
||||||
|
|
||||||
List<InstantAppInfo> instantApps = executeWithConsistentComputerReturning(computer ->
|
Computer computer = snapshotComputer();
|
||||||
mInstantAppRegistry.getInstantApps(computer, userId));
|
List<InstantAppInfo> instantApps = mInstantAppRegistry.getInstantApps(computer, userId);
|
||||||
if (instantApps != null) {
|
if (instantApps != null) {
|
||||||
return new ParceledListSlice<>(instantApps);
|
return new ParceledListSlice<>(instantApps);
|
||||||
}
|
}
|
||||||
@@ -3710,13 +3707,13 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
public void notifyPackageUse(String packageName, int reason) {
|
public void notifyPackageUse(String packageName, int reason) {
|
||||||
final int callingUid = Binder.getCallingUid();
|
final int callingUid = Binder.getCallingUid();
|
||||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||||
boolean notify = executeWithConsistentComputerReturning(computer -> {
|
Computer computer = snapshotComputer();
|
||||||
if (getInstantAppPackageName(callingUid) != null) {
|
final boolean notify;
|
||||||
return isCallerSameApp(packageName, callingUid);
|
if (getInstantAppPackageName(callingUid) != null) {
|
||||||
} else {
|
notify = isCallerSameApp(packageName, callingUid);
|
||||||
return !isInstantAppInternal(packageName, callingUserId, Process.SYSTEM_UID);
|
} else {
|
||||||
}
|
notify = !isInstantAppInternal(packageName, callingUserId, Process.SYSTEM_UID);
|
||||||
});
|
}
|
||||||
if (!notify) {
|
if (!notify) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4255,34 +4252,33 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
|
final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
|
||||||
|
|
||||||
ArraySet<String> changesToCommit = new ArraySet<>();
|
ArraySet<String> changesToCommit = new ArraySet<>();
|
||||||
executeWithConsistentComputer(computer -> {
|
Computer computer = snapshotComputer();
|
||||||
final boolean[] canRestrict = (restrictionFlags != 0)
|
final boolean[] canRestrict = (restrictionFlags != 0)
|
||||||
? mSuspendPackageHelper.canSuspendPackageForUser(computer, packageNames, userId,
|
? mSuspendPackageHelper.canSuspendPackageForUser(computer, packageNames, userId,
|
||||||
callingUid) : null;
|
callingUid) : null;
|
||||||
for (int i = 0; i < packageNames.length; i++) {
|
for (int i = 0; i < packageNames.length; i++) {
|
||||||
final String packageName = packageNames[i];
|
final String packageName = packageNames[i];
|
||||||
final PackageStateInternal packageState =
|
final PackageStateInternal packageState =
|
||||||
computer.getPackageStateInternal(packageName);
|
computer.getPackageStateInternal(packageName);
|
||||||
if (packageState == null
|
if (packageState == null
|
||||||
|| shouldFilterApplication(packageState, callingUid, userId)) {
|
|| computer.shouldFilterApplication(packageState, callingUid, userId)) {
|
||||||
Slog.w(TAG, "Could not find package setting for package: " + packageName
|
Slog.w(TAG, "Could not find package setting for package: " + packageName
|
||||||
+ ". Skipping...");
|
+ ". Skipping...");
|
||||||
unactionedPackages.add(packageName);
|
unactionedPackages.add(packageName);
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (canRestrict != null && !canRestrict[i]) {
|
|
||||||
unactionedPackages.add(packageName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final int oldDistractionFlags = packageState.getUserStateOrDefault(userId)
|
|
||||||
.getDistractionFlags();
|
|
||||||
if (restrictionFlags != oldDistractionFlags) {
|
|
||||||
changedPackagesList.add(packageName);
|
|
||||||
changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
|
||||||
changesToCommit.add(packageName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
if (canRestrict != null && !canRestrict[i]) {
|
||||||
|
unactionedPackages.add(packageName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final int oldDistractionFlags = packageState.getUserStateOrDefault(userId)
|
||||||
|
.getDistractionFlags();
|
||||||
|
if (restrictionFlags != oldDistractionFlags) {
|
||||||
|
changedPackagesList.add(packageName);
|
||||||
|
changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
||||||
|
changesToCommit.add(packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
commitPackageStateMutation(null, mutator -> {
|
commitPackageStateMutation(null, mutator -> {
|
||||||
final int size = changesToCommit.size();
|
final int size = changesToCommit.size();
|
||||||
@@ -4341,8 +4337,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
final int callingUid = Binder.getCallingUid();
|
final int callingUid = Binder.getCallingUid();
|
||||||
enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
|
enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
|
||||||
"setPackagesSuspendedAsUser");
|
"setPackagesSuspendedAsUser");
|
||||||
return mSuspendPackageHelper.setPackagesSuspended(packageNames, suspended, appExtras,
|
return mSuspendPackageHelper.setPackagesSuspended(snapshotComputer(), packageNames,
|
||||||
launcherExtras, dialogInfo, callingPackage, userId, callingUid);
|
suspended, appExtras, launcherExtras, dialogInfo, callingPackage, userId,
|
||||||
|
callingUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -4361,11 +4358,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
return mComputer.isPackageSuspendedForUser(packageName, userId);
|
return mComputer.isPackageSuspendedForUser(packageName, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
|
void unsuspendForSuspendingPackage(@NonNull Computer computer, String suspendingPackage,
|
||||||
|
@UserIdInt int userId) {
|
||||||
// TODO: This can be replaced by a special parameter to iterate all packages, rather than
|
// TODO: This can be replaced by a special parameter to iterate all packages, rather than
|
||||||
// this weird pre-collect of all packages.
|
// this weird pre-collect of all packages.
|
||||||
final String[] allPackages = getPackageStates().keySet().toArray(new String[0]);
|
final String[] allPackages = computer.getPackageStates().keySet().toArray(new String[0]);
|
||||||
mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(
|
mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(computer,
|
||||||
allPackages, suspendingPackage::equals, userId);
|
allPackages, suspendingPackage::equals, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4424,7 +4422,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
throw new SecurityException("Calling uid " + callingUid
|
throw new SecurityException("Calling uid " + callingUid
|
||||||
+ " cannot query getUnsuspendablePackagesForUser for user " + userId);
|
+ " cannot query getUnsuspendablePackagesForUser for user " + userId);
|
||||||
}
|
}
|
||||||
return mSuspendPackageHelper.getUnsuspendablePackagesForUser(
|
return mSuspendPackageHelper.getUnsuspendablePackagesForUser(snapshotComputer(),
|
||||||
packageNames, userId, callingUid);
|
packageNames, userId, callingUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4625,7 +4623,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
PackageStateMutator.InitialState initialState = recordInitialState();
|
PackageStateMutator.InitialState initialState = recordInitialState();
|
||||||
boolean allowed = executeWithConsistentComputerReturningThrowing(implementation);
|
boolean allowed = implementation.apply(snapshotComputer());
|
||||||
if (allowed) {
|
if (allowed) {
|
||||||
// TODO: Need to lock around here to handle mSettings.addInstallerPackageNames,
|
// TODO: Need to lock around here to handle mSettings.addInstallerPackageNames,
|
||||||
// should find an alternative which avoids any race conditions
|
// should find an alternative which avoids any race conditions
|
||||||
@@ -4635,7 +4633,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
targetPackage, state -> state.setInstaller(installerPackageName));
|
targetPackage, state -> state.setInstaller(installerPackageName));
|
||||||
if (result.isPackagesChanged() || result.isStateChanged()) {
|
if (result.isPackagesChanged() || result.isStateChanged()) {
|
||||||
synchronized (mPackageStateWriteLock) {
|
synchronized (mPackageStateWriteLock) {
|
||||||
allowed = executeWithConsistentComputerReturningThrowing(implementation);
|
allowed = implementation.apply(snapshotComputer());
|
||||||
if (allowed) {
|
if (allowed) {
|
||||||
commitPackageStateMutation(null, targetPackage,
|
commitPackageStateMutation(null, targetPackage,
|
||||||
state -> state.setInstaller(installerPackageName));
|
state -> state.setInstaller(installerPackageName));
|
||||||
@@ -4685,12 +4683,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PackageStateMutator.Result result = executeWithConsistentComputerReturning(implementation);
|
PackageStateMutator.Result result = implementation.apply(snapshotComputer());
|
||||||
if (result != null && result.isStateChanged() && !result.isSpecificPackageNull()) {
|
if (result != null && result.isStateChanged() && !result.isSpecificPackageNull()) {
|
||||||
// TODO: Specific return value of what state changed?
|
// TODO: Specific return value of what state changed?
|
||||||
// The installer on record might have changed, retry with lock
|
// The installer on record might have changed, retry with lock
|
||||||
synchronized (mPackageStateWriteLock) {
|
synchronized (mPackageStateWriteLock) {
|
||||||
result = executeWithConsistentComputerReturning(implementation);
|
result = implementation.apply(snapshotComputer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4988,7 +4986,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
|
if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
|
||||||
== PERMISSION_GRANTED) {
|
== PERMISSION_GRANTED) {
|
||||||
unsuspendForSuspendingPackage(packageName, userId);
|
unsuspendForSuspendingPackage(snapshotComputer(), packageName, userId);
|
||||||
removeAllDistractingPackageRestrictions(userId);
|
removeAllDistractingPackageRestrictions(userId);
|
||||||
flushPackageRestrictionsAsUserInternalLocked(userId);
|
flushPackageRestrictionsAsUserInternalLocked(userId);
|
||||||
}
|
}
|
||||||
@@ -5080,17 +5078,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
updateInstantAppInstallerLocked(packageName);
|
updateInstantAppInstallerLocked(packageName);
|
||||||
scheduleWritePackageRestrictions(userId);
|
scheduleWritePackageRestrictions(userId);
|
||||||
|
|
||||||
final ArrayList<String> pendingComponents = mPendingBroadcasts.get(userId, packageName);
|
mPendingBroadcasts.addComponents(userId, packageName, updatedComponents);
|
||||||
if (pendingComponents == null) {
|
|
||||||
mPendingBroadcasts.put(userId, packageName, updatedComponents);
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < updatedComponents.size(); i++) {
|
|
||||||
final String updatedComponent = updatedComponents.get(i);
|
|
||||||
if (!pendingComponents.contains(updatedComponent)) {
|
|
||||||
pendingComponents.add(updatedComponent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
|
if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
|
||||||
mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
|
mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
|
||||||
}
|
}
|
||||||
@@ -5278,7 +5266,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
try {
|
try {
|
||||||
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
|
||||||
TypedXmlSerializer serializer = Xml.resolveSerializer(output);
|
TypedXmlSerializer serializer = Xml.resolveSerializer(output);
|
||||||
mDomainVerificationManager.writeSettings(serializer, true, userId);
|
mDomainVerificationManager.writeSettings(snapshotComputer(), serializer, true,
|
||||||
|
userId);
|
||||||
return output.toByteArray();
|
return output.toByteArray();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -5301,7 +5290,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
// User ID input isn't necessary here as it assumes the user integers match and that
|
// User ID input isn't necessary here as it assumes the user integers match and that
|
||||||
// the only states inside the backup XML are for the target user.
|
// the only states inside the backup XML are for the target user.
|
||||||
mDomainVerificationManager.restoreSettings(parser);
|
mDomainVerificationManager.restoreSettings(snapshotComputer(), parser);
|
||||||
input.close();
|
input.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (DEBUG_BACKUP) {
|
if (DEBUG_BACKUP) {
|
||||||
@@ -5689,48 +5678,48 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
String componentPkgName = componentName.getPackageName();
|
String componentPkgName = componentName.getPackageName();
|
||||||
|
|
||||||
boolean changed = executeWithConsistentComputerReturning(computer -> {
|
Computer computer = snapshotComputer();
|
||||||
int componentUid = getPackageUid(componentPkgName, 0, userId);
|
|
||||||
if (!UserHandle.isSameApp(callingUid, componentUid)) {
|
|
||||||
throw new SecurityException("The calling UID (" + callingUid + ")"
|
|
||||||
+ " does not match the target UID");
|
|
||||||
}
|
|
||||||
|
|
||||||
String allowedCallerPkg =
|
int componentUid = computer.getPackageUid(componentPkgName, 0, userId);
|
||||||
mContext.getString(R.string.config_overrideComponentUiPackage);
|
if (!UserHandle.isSameApp(callingUid, componentUid)) {
|
||||||
if (TextUtils.isEmpty(allowedCallerPkg)) {
|
throw new SecurityException("The calling UID (" + callingUid + ")"
|
||||||
throw new SecurityException( "There is no package defined as allowed to change a "
|
+ " does not match the target UID");
|
||||||
+ "component's label or icon");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int allowedCallerUid = getPackageUid(allowedCallerPkg, PackageManager.MATCH_SYSTEM_ONLY,
|
String allowedCallerPkg =
|
||||||
userId);
|
mContext.getString(R.string.config_overrideComponentUiPackage);
|
||||||
if (allowedCallerUid == -1 || !UserHandle.isSameApp(callingUid, allowedCallerUid)) {
|
if (TextUtils.isEmpty(allowedCallerPkg)) {
|
||||||
throw new SecurityException("The calling UID (" + callingUid + ")"
|
throw new SecurityException( "There is no package defined as allowed to change a "
|
||||||
+ " is not allowed to change a component's label or icon");
|
+ "component's label or icon");
|
||||||
}
|
}
|
||||||
PackageStateInternal packageState = computer.getPackageStateInternal(componentPkgName);
|
|
||||||
if (packageState == null || packageState.getPkg() == null
|
|
||||||
|| (!packageState.isSystem()
|
|
||||||
&& !packageState.getTransientState().isUpdatedSystemApp())) {
|
|
||||||
throw new SecurityException(
|
|
||||||
"Changing the label is not allowed for " + componentName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mComponentResolver.componentExists(componentName)) {
|
int allowedCallerUid = computer.getPackageUid(allowedCallerPkg,
|
||||||
throw new IllegalArgumentException("Component " + componentName + " not found");
|
PackageManager.MATCH_SYSTEM_ONLY, userId);
|
||||||
}
|
if (allowedCallerUid == -1 || !UserHandle.isSameApp(callingUid, allowedCallerUid)) {
|
||||||
|
throw new SecurityException("The calling UID (" + callingUid + ")"
|
||||||
|
+ " is not allowed to change a component's label or icon");
|
||||||
|
}
|
||||||
|
PackageStateInternal packageState = computer.getPackageStateInternal(componentPkgName);
|
||||||
|
if (packageState == null || packageState.getPkg() == null
|
||||||
|
|| (!packageState.isSystem()
|
||||||
|
&& !packageState.getTransientState().isUpdatedSystemApp())) {
|
||||||
|
throw new SecurityException(
|
||||||
|
"Changing the label is not allowed for " + componentName);
|
||||||
|
}
|
||||||
|
|
||||||
Pair<String, Integer> overrideLabelIcon = packageState.getUserStateOrDefault(userId)
|
if (!computer.getComponentResolver().componentExists(componentName)) {
|
||||||
.getOverrideLabelIconForComponent(componentName);
|
throw new IllegalArgumentException("Component " + componentName + " not found");
|
||||||
|
}
|
||||||
|
|
||||||
String existingLabel = overrideLabelIcon == null ? null : overrideLabelIcon.first;
|
Pair<String, Integer> overrideLabelIcon = packageState.getUserStateOrDefault(userId)
|
||||||
Integer existingIcon = overrideLabelIcon == null ? null : overrideLabelIcon.second;
|
.getOverrideLabelIconForComponent(componentName);
|
||||||
|
|
||||||
return !TextUtils.equals(existingLabel, nonLocalizedLabel)
|
String existingLabel = overrideLabelIcon == null ? null : overrideLabelIcon.first;
|
||||||
|| !Objects.equals(existingIcon, icon);
|
Integer existingIcon = overrideLabelIcon == null ? null : overrideLabelIcon.second;
|
||||||
});
|
|
||||||
if (!changed) {
|
if (TextUtils.equals(existingLabel, nonLocalizedLabel)
|
||||||
|
&& Objects.equals(existingIcon, icon)) {
|
||||||
|
// Nothing changed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5738,16 +5727,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
state -> state.userState(userId)
|
state -> state.userState(userId)
|
||||||
.setComponentLabelIcon(componentName, nonLocalizedLabel, icon));
|
.setComponentLabelIcon(componentName, nonLocalizedLabel, icon));
|
||||||
|
|
||||||
ArrayList<String> components = mPendingBroadcasts.get(userId, componentPkgName);
|
mPendingBroadcasts.addComponent(userId, componentPkgName, componentName.getClassName());
|
||||||
if (components == null) {
|
|
||||||
components = new ArrayList<>();
|
|
||||||
mPendingBroadcasts.put(userId, componentPkgName, components);
|
|
||||||
}
|
|
||||||
|
|
||||||
String className = componentName.getClassName();
|
|
||||||
if (!components.contains(className)) {
|
|
||||||
components.add(className);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
|
if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
|
||||||
mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
|
mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
|
||||||
@@ -5956,6 +5936,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
// packageName -> list of components to send broadcasts now
|
// packageName -> list of components to send broadcasts now
|
||||||
final ArrayMap<String, ArrayList<String>> sendNowBroadcasts = new ArrayMap<>(targetSize);
|
final ArrayMap<String, ArrayList<String>> sendNowBroadcasts = new ArrayMap<>(targetSize);
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
Computer computer = snapshotComputer();
|
||||||
boolean scheduleBroadcastMessage = false;
|
boolean scheduleBroadcastMessage = false;
|
||||||
boolean isSynchronous = false;
|
boolean isSynchronous = false;
|
||||||
boolean anyChanged = false;
|
boolean anyChanged = false;
|
||||||
@@ -5967,8 +5948,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
// update enabled settings
|
// update enabled settings
|
||||||
final ComponentEnabledSetting setting = settings.get(i);
|
final ComponentEnabledSetting setting = settings.get(i);
|
||||||
final String packageName = setting.getPackageName();
|
final String packageName = setting.getPackageName();
|
||||||
if (!setEnabledSettingInternalLocked(pkgSettings.get(packageName), setting,
|
if (!setEnabledSettingInternalLocked(computer, pkgSettings.get(packageName),
|
||||||
userId, callingPackage)) {
|
setting, userId, callingPackage)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
anyChanged = true;
|
anyChanged = true;
|
||||||
@@ -5979,26 +5960,18 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
// collect broadcast list for the package
|
// collect broadcast list for the package
|
||||||
final String componentName = setting.isComponent()
|
final String componentName = setting.isComponent()
|
||||||
? setting.getClassName() : packageName;
|
? setting.getClassName() : packageName;
|
||||||
ArrayList<String> componentList = sendNowBroadcasts.get(packageName);
|
|
||||||
if (componentList == null) {
|
|
||||||
componentList = mPendingBroadcasts.get(userId, packageName);
|
|
||||||
}
|
|
||||||
final boolean newPackage = componentList == null;
|
|
||||||
if (newPackage) {
|
|
||||||
componentList = new ArrayList<>();
|
|
||||||
}
|
|
||||||
if (!componentList.contains(componentName)) {
|
|
||||||
componentList.add(componentName);
|
|
||||||
}
|
|
||||||
if ((setting.getEnabledFlags() & PackageManager.DONT_KILL_APP) == 0) {
|
if ((setting.getEnabledFlags() & PackageManager.DONT_KILL_APP) == 0) {
|
||||||
|
ArrayList<String> componentList = sendNowBroadcasts.get(packageName);
|
||||||
|
componentList = componentList == null ? new ArrayList<>() : componentList;
|
||||||
|
if (!componentList.contains(componentName)) {
|
||||||
|
componentList.add(componentName);
|
||||||
|
}
|
||||||
sendNowBroadcasts.put(packageName, componentList);
|
sendNowBroadcasts.put(packageName, componentList);
|
||||||
// Purge entry from pending broadcast list if another one exists already
|
// Purge entry from pending broadcast list if another one exists already
|
||||||
// since we are sending one right away.
|
// since we are sending one right away.
|
||||||
mPendingBroadcasts.remove(userId, packageName);
|
mPendingBroadcasts.remove(userId, packageName);
|
||||||
} else {
|
} else {
|
||||||
if (newPackage) {
|
mPendingBroadcasts.addComponent(userId, packageName, componentName);
|
||||||
mPendingBroadcasts.put(userId, packageName, componentList);
|
|
||||||
}
|
|
||||||
scheduleBroadcastMessage = true;
|
scheduleBroadcastMessage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6041,8 +6014,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setEnabledSettingInternalLocked(PackageSetting pkgSetting,
|
private boolean setEnabledSettingInternalLocked(@NonNull Computer computer,
|
||||||
ComponentEnabledSetting setting, int userId, String callingPackage) {
|
PackageSetting pkgSetting, ComponentEnabledSetting setting, @UserIdInt int userId,
|
||||||
|
String callingPackage) {
|
||||||
final int newState = setting.getEnabledState();
|
final int newState = setting.getEnabledState();
|
||||||
final String packageName = setting.getPackageName();
|
final String packageName = setting.getPackageName();
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
@@ -6061,7 +6035,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
// This app should not generally be allowed to get disabled by the UI, but
|
// This app should not generally be allowed to get disabled by the UI, but
|
||||||
// if it ever does, we don't want to end up with some of the user's apps
|
// if it ever does, we don't want to end up with some of the user's apps
|
||||||
// permanently suspended.
|
// permanently suspended.
|
||||||
unsuspendForSuspendingPackage(packageName, userId);
|
unsuspendForSuspendingPackage(computer, packageName, userId);
|
||||||
removeAllDistractingPackageRestrictions(userId);
|
removeAllDistractingPackageRestrictions(userId);
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
@@ -6152,11 +6126,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
|
public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
|
||||||
if (!mUserManager.exists(userId)) return;
|
if (!mUserManager.exists(userId)) return;
|
||||||
final int callingUid = Binder.getCallingUid();
|
final int callingUid = Binder.getCallingUid();
|
||||||
Pair<Boolean, String> wasNotLaunchedAndInstallerPackageName =
|
final Computer computer = snapshotComputer();
|
||||||
executeWithConsistentComputerReturningThrowing(computer -> {
|
if (computer.getInstantAppPackageName(callingUid) == null) {
|
||||||
if (computer.getInstantAppPackageName(callingUid) != null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final int permission = mContext.checkCallingOrSelfPermission(
|
final int permission = mContext.checkCallingOrSelfPermission(
|
||||||
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
|
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
|
||||||
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
|
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
|
||||||
@@ -6171,36 +6142,30 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
true /* requireFullPermission */, true /* checkShell */, "stop package");
|
true /* requireFullPermission */, true /* checkShell */, "stop package");
|
||||||
|
|
||||||
final PackageStateInternal packageState = computer.getPackageStateInternal(packageName);
|
final PackageStateInternal packageState = computer.getPackageStateInternal(packageName);
|
||||||
final PackageUserState PackageUserState = packageState == null
|
final PackageUserState packageUserState = packageState == null
|
||||||
? null : packageState.getUserStateOrDefault(userId);
|
? null : packageState.getUserStateOrDefault(userId);
|
||||||
if (packageState == null
|
if (packageState != null
|
||||||
|| computer.shouldFilterApplication(packageState, callingUid, userId)
|
&& !computer.shouldFilterApplication(packageState, callingUid, userId)
|
||||||
|| PackageUserState.isStopped() == stopped) {
|
&& packageUserState.isStopped() != stopped) {
|
||||||
return null;
|
boolean wasNotLaunched = packageUserState.isNotLaunched();
|
||||||
}
|
commitPackageStateMutation(null, packageName, state -> {
|
||||||
|
PackageUserStateWrite userState = state.userState(userId);
|
||||||
|
userState.setStopped(stopped);
|
||||||
|
if (wasNotLaunched) {
|
||||||
|
userState.setNotLaunched(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return Pair.create(PackageUserState.isNotLaunched(),
|
|
||||||
packageState.getInstallSource().installerPackageName);
|
|
||||||
});
|
|
||||||
if (wasNotLaunchedAndInstallerPackageName != null) {
|
|
||||||
boolean wasNotLaunched = wasNotLaunchedAndInstallerPackageName.first;
|
|
||||||
|
|
||||||
commitPackageStateMutation(null, packageName, packageState -> {
|
|
||||||
PackageUserStateWrite userState = packageState.userState(userId);
|
|
||||||
userState.setStopped(stopped);
|
|
||||||
if (wasNotLaunched) {
|
if (wasNotLaunched) {
|
||||||
userState.setNotLaunched(false);
|
final String installerPackageName =
|
||||||
|
packageState.getInstallSource().installerPackageName;
|
||||||
|
if (installerPackageName != null) {
|
||||||
|
notifyFirstLaunch(packageName, installerPackageName, userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (wasNotLaunched) {
|
scheduleWritePackageRestrictions(userId);
|
||||||
final String installerPackageName = wasNotLaunchedAndInstallerPackageName.second;
|
|
||||||
if (installerPackageName != null) {
|
|
||||||
notifyFirstLaunch(packageName, installerPackageName, userId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduleWritePackageRestrictions(userId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this would cause the app to leave force-stop, then also make sure to unhibernate the
|
// If this would cause the app to leave force-stop, then also make sure to unhibernate the
|
||||||
@@ -6687,7 +6652,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
"Only package verification agents can read the verifier device identity");
|
"Only package verification agents can read the verifier device identity");
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
return mSettings.getVerifierDeviceIdentityLPw();
|
return mSettings.getVerifierDeviceIdentityLPw(mLiveComputer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7026,15 +6991,16 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeAllNonSystemPackageSuspensions(int userId) {
|
public void removeAllNonSystemPackageSuspensions(int userId) {
|
||||||
final String[] allPackages = mComputer.getAllAvailablePackageNames();
|
final Computer computer = snapshotComputer();
|
||||||
mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(allPackages,
|
final String[] allPackages = computer.getAllAvailablePackageNames();
|
||||||
|
mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(computer, allPackages,
|
||||||
(suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
|
(suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
|
||||||
userId);
|
userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeNonSystemPackageSuspensions(String packageName, int userId) {
|
public void removeNonSystemPackageSuspensions(String packageName, int userId) {
|
||||||
mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(
|
mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(snapshotComputer(),
|
||||||
new String[]{packageName},
|
new String[]{packageName},
|
||||||
(suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
|
(suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
|
||||||
userId);
|
userId);
|
||||||
@@ -7233,29 +7199,29 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
@Override
|
@Override
|
||||||
public void grantImplicitAccess(int userId, Intent intent,
|
public void grantImplicitAccess(int userId, Intent intent,
|
||||||
int recipientAppId, int visibleUid, boolean direct, boolean retainOnUpdate) {
|
int recipientAppId, int visibleUid, boolean direct, boolean retainOnUpdate) {
|
||||||
boolean accessGranted = executeWithConsistentComputerReturning(computer -> {
|
Computer computer = snapshotComputer();
|
||||||
final AndroidPackage visiblePackage = computer.getPackage(visibleUid);
|
final AndroidPackage visiblePackage = computer.getPackage(visibleUid);
|
||||||
final int recipientUid = UserHandle.getUid(userId, recipientAppId);
|
final int recipientUid = UserHandle.getUid(userId, recipientAppId);
|
||||||
if (visiblePackage == null || computer.getPackage(recipientUid) == null) {
|
if (visiblePackage == null || computer.getPackage(recipientUid) == null) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean instantApp = computer.isInstantAppInternal(
|
final boolean instantApp = computer.isInstantAppInternal(
|
||||||
visiblePackage.getPackageName(), userId, visibleUid);
|
visiblePackage.getPackageName(), userId, visibleUid);
|
||||||
if (instantApp) {
|
final boolean accessGranted;
|
||||||
if (!direct) {
|
if (instantApp) {
|
||||||
// if the interaction that lead to this granting access to an instant app
|
if (!direct) {
|
||||||
// was indirect (i.e.: URI permission grant), do not actually execute the
|
// if the interaction that lead to this granting access to an instant app
|
||||||
// grant.
|
// was indirect (i.e.: URI permission grant), do not actually execute the
|
||||||
return false;
|
// grant.
|
||||||
}
|
return;
|
||||||
return mInstantAppRegistry.grantInstantAccess(userId, intent,
|
|
||||||
recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
|
|
||||||
} else {
|
|
||||||
return mAppsFilter.grantImplicitAccess(recipientUid, visibleUid,
|
|
||||||
retainOnUpdate);
|
|
||||||
}
|
}
|
||||||
});
|
accessGranted = mInstantAppRegistry.grantInstantAccess(userId, intent,
|
||||||
|
recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
|
||||||
|
} else {
|
||||||
|
accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid,
|
||||||
|
retainOnUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
if (accessGranted) {
|
if (accessGranted) {
|
||||||
ApplicationPackageManager.invalidateGetPackagesForUidCache();
|
ApplicationPackageManager.invalidateGetPackagesForUidCache();
|
||||||
@@ -7271,8 +7237,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pruneInstantApps() {
|
public void pruneInstantApps() {
|
||||||
executeWithConsistentComputer(computer ->
|
mInstantAppRegistry.pruneInstantApps(snapshotComputer());
|
||||||
mInstantAppRegistry.pruneInstantApps(computer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -7680,7 +7645,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
|
public void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
|
||||||
PackageManagerService.this.unsuspendForSuspendingPackage(packageName, affectedUser);
|
PackageManagerService.this.unsuspendForSuspendingPackage(snapshotComputer(),
|
||||||
|
packageName, affectedUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -7743,52 +7709,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
return PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
|
return PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void withPackageSettingsSnapshot(
|
|
||||||
@NonNull Consumer<Function<String, PackageStateInternal>> block) {
|
|
||||||
executeWithConsistentComputer(computer ->
|
|
||||||
block.accept(computer::getPackageStateInternal));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <Output> Output withPackageSettingsSnapshotReturning(
|
|
||||||
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageStateInternal>,
|
|
||||||
Output> block) {
|
|
||||||
return executeWithConsistentComputerReturning(computer ->
|
|
||||||
block.apply(computer::getPackageStateInternal));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
|
|
||||||
@NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String,
|
|
||||||
PackageStateInternal>, ExceptionType> block) throws ExceptionType {
|
|
||||||
executeWithConsistentComputerThrowing(computer ->
|
|
||||||
block.accept(computer::getPackageStateInternal));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
|
|
||||||
withPackageSettingsSnapshotThrowing2(
|
|
||||||
@NonNull FunctionalUtils.ThrowingChecked2Consumer<
|
|
||||||
Function<String, PackageStateInternal>, ExceptionOne,
|
|
||||||
ExceptionTwo> block)
|
|
||||||
throws ExceptionOne, ExceptionTwo {
|
|
||||||
executeWithConsistentComputerThrowing2(
|
|
||||||
(FunctionalUtils.ThrowingChecked2Consumer<Computer, ExceptionOne,
|
|
||||||
ExceptionTwo>) computer -> block.accept(computer::getPackageStateInternal));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <Output, ExceptionType extends Exception> Output
|
|
||||||
withPackageSettingsSnapshotReturningThrowing(
|
|
||||||
@NonNull FunctionalUtils.ThrowingCheckedFunction<
|
|
||||||
Function<String, PackageStateInternal>, Output,
|
|
||||||
ExceptionType> block)
|
|
||||||
throws ExceptionType {
|
|
||||||
return executeWithConsistentComputerReturningThrowing(computer ->
|
|
||||||
block.apply(computer::getPackageStateInternal));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reconcileAppsData(int userId, @StorageManager.StorageFlags int flags,
|
public void reconcileAppsData(int userId, @StorageManager.StorageFlags int flags,
|
||||||
boolean migrateAppsData) {
|
boolean migrateAppsData) {
|
||||||
@@ -7834,70 +7754,59 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
@NonNull Set<String> outUpdatedPackageNames) {
|
@NonNull Set<String> outUpdatedPackageNames) {
|
||||||
synchronized (mOverlayPathsLock) {
|
synchronized (mOverlayPathsLock) {
|
||||||
final ArrayMap<String, ArraySet<String>> libNameToModifiedDependents = new ArrayMap<>();
|
final ArrayMap<String, ArraySet<String>> libNameToModifiedDependents = new ArrayMap<>();
|
||||||
Boolean targetModified = executeWithConsistentComputerReturning(computer -> {
|
Computer computer = snapshotComputer();
|
||||||
final PackageStateInternal packageState = computer.getPackageStateInternal(
|
final PackageStateInternal packageState = computer.getPackageStateInternal(
|
||||||
targetPackageName);
|
targetPackageName);
|
||||||
final AndroidPackage targetPkg =
|
final AndroidPackage targetPkg = packageState == null ? null : packageState.getPkg();
|
||||||
packageState == null ? null : packageState.getPkg();
|
if (targetPackageName == null || targetPkg == null) {
|
||||||
if (targetPackageName == null || targetPkg == null) {
|
Slog.e(TAG, "failed to find package " + targetPackageName);
|
||||||
Slog.e(TAG, "failed to find package " + targetPackageName);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Objects.equals(packageState.getUserStateOrDefault(userId).getOverlayPaths(),
|
|
||||||
newOverlayPaths)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetPkg.getLibraryNames() != null) {
|
|
||||||
// Set the overlay paths for dependencies of the shared library.
|
|
||||||
for (final String libName : targetPkg.getLibraryNames()) {
|
|
||||||
ArraySet<String> modifiedDependents = null;
|
|
||||||
|
|
||||||
final SharedLibraryInfo info = computer.getSharedLibraryInfo(libName,
|
|
||||||
SharedLibraryInfo.VERSION_UNDEFINED);
|
|
||||||
if (info == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final List<VersionedPackage> dependents = computer
|
|
||||||
.getPackagesUsingSharedLibrary(info, 0, Process.SYSTEM_UID, userId);
|
|
||||||
if (dependents == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (final VersionedPackage dependent : dependents) {
|
|
||||||
final PackageStateInternal dependentState =
|
|
||||||
computer.getPackageStateInternal(dependent.getPackageName());
|
|
||||||
if (dependentState == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(dependentState.getUserStateOrDefault(userId)
|
|
||||||
.getSharedLibraryOverlayPaths()
|
|
||||||
.get(libName), newOverlayPaths)) {
|
|
||||||
String dependentPackageName = dependent.getPackageName();
|
|
||||||
modifiedDependents = ArrayUtils.add(modifiedDependents,
|
|
||||||
dependentPackageName);
|
|
||||||
outUpdatedPackageNames.add(dependentPackageName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modifiedDependents != null) {
|
|
||||||
libNameToModifiedDependents.put(libName, modifiedDependents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outUpdatedPackageNames.add(targetPackageName);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (targetModified == null) {
|
|
||||||
// Null indicates error
|
|
||||||
return false;
|
return false;
|
||||||
} else if (!targetModified) {
|
}
|
||||||
// Treat non-modification as a successful commit
|
|
||||||
|
if (Objects.equals(packageState.getUserStateOrDefault(userId).getOverlayPaths(),
|
||||||
|
newOverlayPaths)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (targetPkg.getLibraryNames() != null) {
|
||||||
|
// Set the overlay paths for dependencies of the shared library.
|
||||||
|
for (final String libName : targetPkg.getLibraryNames()) {
|
||||||
|
ArraySet<String> modifiedDependents = null;
|
||||||
|
|
||||||
|
final SharedLibraryInfo info = computer.getSharedLibraryInfo(libName,
|
||||||
|
SharedLibraryInfo.VERSION_UNDEFINED);
|
||||||
|
if (info == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final List<VersionedPackage> dependents = computer
|
||||||
|
.getPackagesUsingSharedLibrary(info, 0, Process.SYSTEM_UID, userId);
|
||||||
|
if (dependents == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (final VersionedPackage dependent : dependents) {
|
||||||
|
final PackageStateInternal dependentState =
|
||||||
|
computer.getPackageStateInternal(dependent.getPackageName());
|
||||||
|
if (dependentState == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(dependentState.getUserStateOrDefault(userId)
|
||||||
|
.getSharedLibraryOverlayPaths()
|
||||||
|
.get(libName), newOverlayPaths)) {
|
||||||
|
String dependentPackageName = dependent.getPackageName();
|
||||||
|
modifiedDependents = ArrayUtils.add(modifiedDependents,
|
||||||
|
dependentPackageName);
|
||||||
|
outUpdatedPackageNames.add(dependentPackageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modifiedDependents != null) {
|
||||||
|
libNameToModifiedDependents.put(libName, modifiedDependents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outUpdatedPackageNames.add(targetPackageName);
|
||||||
|
|
||||||
commitPackageStateMutation(null, mutator -> {
|
commitPackageStateMutation(null, mutator -> {
|
||||||
mutator.forPackage(targetPackageName)
|
mutator.forPackage(targetPackageName)
|
||||||
.userState(userId)
|
.userState(userId)
|
||||||
@@ -8062,36 +7971,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
forEachPackageState(mComputer.getPackageStates(), actionWrapped);
|
forEachPackageState(mComputer.getPackageStates(), actionWrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make private
|
|
||||||
void executeWithConsistentComputer(
|
|
||||||
@NonNull FunctionalUtils.ThrowingConsumer<Computer> consumer) {
|
|
||||||
consumer.accept(snapshotComputer());
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> T executeWithConsistentComputerReturning(
|
|
||||||
@NonNull FunctionalUtils.ThrowingFunction<Computer, T> function) {
|
|
||||||
return function.apply(snapshotComputer());
|
|
||||||
}
|
|
||||||
|
|
||||||
private <ExceptionType extends Exception> void executeWithConsistentComputerThrowing(
|
|
||||||
@NonNull FunctionalUtils.ThrowingCheckedConsumer<Computer, ExceptionType> consumer)
|
|
||||||
throws ExceptionType {
|
|
||||||
consumer.accept(snapshotComputer());
|
|
||||||
}
|
|
||||||
|
|
||||||
private <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
|
|
||||||
executeWithConsistentComputerThrowing2(
|
|
||||||
@NonNull FunctionalUtils.ThrowingChecked2Consumer<Computer, ExceptionOne,
|
|
||||||
ExceptionTwo> consumer) throws ExceptionOne, ExceptionTwo {
|
|
||||||
consumer.accept(snapshotComputer());
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T, ExceptionType extends Exception> T executeWithConsistentComputerReturningThrowing(
|
|
||||||
@NonNull FunctionalUtils.ThrowingCheckedFunction<Computer, T, ExceptionType> function)
|
|
||||||
throws ExceptionType {
|
|
||||||
return function.apply(snapshotComputer());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isHistoricalPackageUsageAvailable() {
|
boolean isHistoricalPackageUsageAvailable() {
|
||||||
return mPackageUsage.isHistoricalPackageUsageAvailable();
|
return mPackageUsage.isHistoricalPackageUsageAvailable();
|
||||||
}
|
}
|
||||||
@@ -8357,7 +8236,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
*/
|
*/
|
||||||
void writeSettingsLPrTEMP() {
|
void writeSettingsLPrTEMP() {
|
||||||
mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions);
|
mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions);
|
||||||
mSettings.writeLPr();
|
mSettings.writeLPr(mLiveComputer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -8856,7 +8735,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
void notifyInstantAppPackageInstalled(String packageName, int[] newUsers) {
|
void notifyInstantAppPackageInstalled(String packageName, int[] newUsers) {
|
||||||
executeWithConsistentComputer(computer ->
|
mInstantAppRegistry.onPackageInstalled(snapshotComputer(), packageName, newUsers);
|
||||||
mInstantAppRegistry.onPackageInstalled(computer, packageName, newUsers));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,17 @@
|
|||||||
|
|
||||||
package com.android.server.pm;
|
package com.android.server.pm;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of pending broadcasts for aggregating enable/disable of components.
|
* Set of pending broadcasts for aggregating enable/disable of components.
|
||||||
@@ -29,65 +34,111 @@ import java.util.ArrayList;
|
|||||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||||
public final class PendingPackageBroadcasts {
|
public final class PendingPackageBroadcasts {
|
||||||
|
|
||||||
|
private final Object mLock = new PackageManagerTracedLock();
|
||||||
|
|
||||||
// for each user id, a map of <package name -> components within that package>
|
// for each user id, a map of <package name -> components within that package>
|
||||||
|
@GuardedBy("mLock")
|
||||||
final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
|
final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
|
||||||
|
|
||||||
public PendingPackageBroadcasts() {
|
public PendingPackageBroadcasts() {
|
||||||
mUidMap = new SparseArray<>(2);
|
mUidMap = new SparseArray<>(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<String> get(int userId, String packageName) {
|
public boolean hasPackage(@UserIdInt int userId, @NonNull String packageName) {
|
||||||
ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
|
synchronized (mLock) {
|
||||||
return packages.get(packageName);
|
final ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
|
||||||
|
return packages != null && packages.containsKey(packageName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(int userId, String packageName, ArrayList<String> components) {
|
public void put(int userId, String packageName, ArrayList<String> components) {
|
||||||
ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
|
synchronized (mLock) {
|
||||||
packages.put(packageName, components);
|
ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
|
||||||
|
packages.put(packageName, components);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addComponent(@UserIdInt int userId, @NonNull String packageName,
|
||||||
|
@NonNull String componentClassName) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
ArrayList<String> components = getOrAllocate(userId, packageName);
|
||||||
|
if (!components.contains(componentClassName)) {
|
||||||
|
components.add(componentClassName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addComponents(@UserIdInt int userId, @NonNull String packageName,
|
||||||
|
@NonNull List<String> componentClassNames) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
ArrayList<String> components = getOrAllocate(userId, packageName);
|
||||||
|
for (int index = 0; index < componentClassNames.size(); index++) {
|
||||||
|
String componentClassName = componentClassNames.get(index);
|
||||||
|
if (!components.contains(componentClassName)) {
|
||||||
|
components.add(componentClassName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(int userId, String packageName) {
|
public void remove(int userId, String packageName) {
|
||||||
ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
|
synchronized (mLock) {
|
||||||
if (packages != null) {
|
ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
|
||||||
packages.remove(packageName);
|
if (packages != null) {
|
||||||
|
packages.remove(packageName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(int userId) {
|
public void remove(int userId) {
|
||||||
mUidMap.remove(userId);
|
synchronized (mLock) {
|
||||||
}
|
mUidMap.remove(userId);
|
||||||
|
}
|
||||||
public int userIdCount() {
|
}
|
||||||
return mUidMap.size();
|
|
||||||
}
|
@Nullable
|
||||||
|
public SparseArray<ArrayMap<String, ArrayList<String>>> copiedMap() {
|
||||||
public int userIdAt(int n) {
|
synchronized (mLock) {
|
||||||
return mUidMap.keyAt(n);
|
SparseArray<ArrayMap<String, ArrayList<String>>> copy = new SparseArray<>();
|
||||||
}
|
for (int userIdIndex = 0; userIdIndex < mUidMap.size(); userIdIndex++) {
|
||||||
|
final ArrayMap<String, ArrayList<String>> packages = mUidMap.valueAt(userIdIndex);
|
||||||
public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
|
ArrayMap<String, ArrayList<String>> packagesCopy = new ArrayMap<>();
|
||||||
return mUidMap.get(userId);
|
for (int packagesIndex = 0; packagesIndex < packages.size(); packagesIndex++) {
|
||||||
}
|
packagesCopy.put(packages.keyAt(packagesIndex),
|
||||||
|
new ArrayList<>(packages.valueAt(packagesIndex)));
|
||||||
public int size() {
|
}
|
||||||
// total number of pending broadcast entries across all userIds
|
copy.put(mUidMap.keyAt(userIdIndex), packagesCopy);
|
||||||
int num = 0;
|
}
|
||||||
for (int i = 0; i < mUidMap.size(); i++) {
|
return copy;
|
||||||
num += mUidMap.valueAt(i).size();
|
|
||||||
}
|
}
|
||||||
return num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
mUidMap.clear();
|
synchronized (mLock) {
|
||||||
|
mUidMap.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
|
private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
|
||||||
ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
|
synchronized (mLock) {
|
||||||
if (map == null) {
|
ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
|
||||||
map = new ArrayMap<>();
|
if (map == null) {
|
||||||
mUidMap.put(userId, map);
|
map = new ArrayMap<>();
|
||||||
|
mUidMap.put(userId, map);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<String> getOrAllocate(int userId, @NonNull String packageName) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
|
||||||
|
if (map == null) {
|
||||||
|
map = new ArrayMap<>();
|
||||||
|
mUidMap.put(userId, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map.computeIfAbsent(packageName, k -> new ArrayList<>());
|
||||||
}
|
}
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2432,7 +2432,7 @@ public final class Settings implements Watchable, Snappable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeLPr() {
|
void writeLPr(@NonNull Computer computer) {
|
||||||
//Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
|
//Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
|
||||||
|
|
||||||
final long startTime = SystemClock.uptimeMillis();
|
final long startTime = SystemClock.uptimeMillis();
|
||||||
@@ -2524,8 +2524,8 @@ public final class Settings implements Watchable, Snappable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mDomainVerificationManager.writeSettings(serializer, false /* includeSignatures */,
|
mDomainVerificationManager.writeSettings(computer, serializer,
|
||||||
UserHandle.USER_ALL);
|
false /* includeSignatures */, UserHandle.USER_ALL);
|
||||||
|
|
||||||
mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
|
mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
|
||||||
|
|
||||||
@@ -2967,7 +2967,7 @@ public final class Settings implements Watchable, Snappable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean readLPw(@NonNull List<UserInfo> users) {
|
boolean readLPw(@NonNull Computer computer, @NonNull List<UserInfo> users) {
|
||||||
FileInputStream str = null;
|
FileInputStream str = null;
|
||||||
if (mBackupSettingsFilename.exists()) {
|
if (mBackupSettingsFilename.exists()) {
|
||||||
try {
|
try {
|
||||||
@@ -3111,7 +3111,7 @@ public final class Settings implements Watchable, Snappable {
|
|||||||
ver.databaseVersion = parser.getAttributeInt(null, ATTR_DATABASE_VERSION);
|
ver.databaseVersion = parser.getAttributeInt(null, ATTR_DATABASE_VERSION);
|
||||||
ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
|
ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
|
||||||
} else if (tagName.equals(DomainVerificationPersistence.TAG_DOMAIN_VERIFICATIONS)) {
|
} else if (tagName.equals(DomainVerificationPersistence.TAG_DOMAIN_VERIFICATIONS)) {
|
||||||
mDomainVerificationManager.readSettings(parser);
|
mDomainVerificationManager.readSettings(computer, parser);
|
||||||
} else if (tagName.equals(
|
} else if (tagName.equals(
|
||||||
DomainVerificationLegacySettings.TAG_DOMAIN_VERIFICATIONS_LEGACY)) {
|
DomainVerificationLegacySettings.TAG_DOMAIN_VERIFICATIONS_LEGACY)) {
|
||||||
mDomainVerificationManager.readLegacySettings(parser);
|
mDomainVerificationManager.readLegacySettings(parser);
|
||||||
@@ -4287,11 +4287,11 @@ public final class Settings implements Watchable, Snappable {
|
|||||||
return Process.FIRST_APPLICATION_UID + size;
|
return Process.FIRST_APPLICATION_UID + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
|
public VerifierDeviceIdentity getVerifierDeviceIdentityLPw(@NonNull Computer computer) {
|
||||||
if (mVerifierDeviceIdentity == null) {
|
if (mVerifierDeviceIdentity == null) {
|
||||||
mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
|
mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
|
||||||
|
|
||||||
writeLPr();
|
writeLPr(computer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mVerifierDeviceIdentity;
|
return mVerifierDeviceIdentity;
|
||||||
|
|||||||
@@ -321,7 +321,8 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
|
|||||||
* on the device.
|
* on the device.
|
||||||
* @return {@code true} if the available storage space is reached.
|
* @return {@code true} if the available storage space is reached.
|
||||||
*/
|
*/
|
||||||
boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
|
boolean pruneUnusedStaticSharedLibraries(@NonNull Computer computer, long neededSpace,
|
||||||
|
long maxCachePeriod)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
final StorageManager storage = mInjector.getSystemService(StorageManager.class);
|
final StorageManager storage = mInjector.getSystemService(StorageManager.class);
|
||||||
final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
|
final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
|
||||||
@@ -332,38 +333,36 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
|
|||||||
// Important: We skip shared libs used for some user since
|
// Important: We skip shared libs used for some user since
|
||||||
// in such a case we need to keep the APK on the device. The check for
|
// in such a case we need to keep the APK on the device. The check for
|
||||||
// a lib being used for any user is performed by the uninstall call.
|
// a lib being used for any user is performed by the uninstall call.
|
||||||
mPm.executeWithConsistentComputer(computer -> {
|
final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
|
||||||
final WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>
|
sharedLibraries = computer.getSharedLibraries();
|
||||||
sharedLibraries = computer.getSharedLibraries();
|
final int libCount = sharedLibraries.size();
|
||||||
final int libCount = sharedLibraries.size();
|
for (int i = 0; i < libCount; i++) {
|
||||||
for (int i = 0; i < libCount; i++) {
|
final WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
|
||||||
final WatchedLongSparseArray<SharedLibraryInfo> versionedLib =
|
sharedLibraries.valueAt(i);
|
||||||
sharedLibraries.valueAt(i);
|
if (versionedLib == null) {
|
||||||
if (versionedLib == null) {
|
continue;
|
||||||
|
}
|
||||||
|
final int versionCount = versionedLib.size();
|
||||||
|
for (int j = 0; j < versionCount; j++) {
|
||||||
|
SharedLibraryInfo libInfo = versionedLib.valueAt(j);
|
||||||
|
final PackageStateInternal ps = getLibraryPackage(computer, libInfo);
|
||||||
|
if (ps == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final int versionCount = versionedLib.size();
|
// Skip unused libs cached less than the min period to prevent pruning a lib
|
||||||
for (int j = 0; j < versionCount; j++) {
|
// needed by a subsequently installed package.
|
||||||
SharedLibraryInfo libInfo = versionedLib.valueAt(j);
|
if (now - ps.getLastUpdateTime() < maxCachePeriod) {
|
||||||
final PackageStateInternal ps = getLibraryPackage(computer, libInfo);
|
continue;
|
||||||
if (ps == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Skip unused libs cached less than the min period to prevent pruning a lib
|
|
||||||
// needed by a subsequently installed package.
|
|
||||||
if (now - ps.getLastUpdateTime() < maxCachePeriod) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps.getPkg().isSystem()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
packagesToDelete.add(new VersionedPackage(ps.getPkg().getPackageName(),
|
|
||||||
libInfo.getDeclaringPackage().getLongVersionCode()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.getPkg().isSystem()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
packagesToDelete.add(new VersionedPackage(ps.getPkg().getPackageName(),
|
||||||
|
libInfo.getDeclaringPackage().getLongVersionCode()));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
final int packageCount = packagesToDelete.size();
|
final int packageCount = packagesToDelete.size();
|
||||||
for (int i = 0; i < packageCount; i++) {
|
for (int i = 0; i < packageCount; i++) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import static com.android.server.pm.PackageManagerService.TAG;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.IActivityManager;
|
import android.app.IActivityManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -99,10 +100,10 @@ public final class SuspendPackageHelper {
|
|||||||
* @return The names of failed packages.
|
* @return The names of failed packages.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
String[] setPackagesSuspended(@Nullable String[] packageNames, boolean suspended,
|
String[] setPackagesSuspended(@NonNull Computer computer, @Nullable String[] packageNames,
|
||||||
@Nullable PersistableBundle appExtras, @Nullable PersistableBundle launcherExtras,
|
boolean suspended, @Nullable PersistableBundle appExtras,
|
||||||
@Nullable SuspendDialogInfo dialogInfo, @NonNull String callingPackage,
|
@Nullable PersistableBundle launcherExtras, @Nullable SuspendDialogInfo dialogInfo,
|
||||||
int userId, int callingUid) {
|
@NonNull String callingPackage, @UserIdInt int userId, int callingUid) {
|
||||||
if (ArrayUtils.isEmpty(packageNames)) {
|
if (ArrayUtils.isEmpty(packageNames)) {
|
||||||
return packageNames;
|
return packageNames;
|
||||||
}
|
}
|
||||||
@@ -121,62 +122,60 @@ public final class SuspendPackageHelper {
|
|||||||
|
|
||||||
ArraySet<String> modifiedPackages = new ArraySet<>();
|
ArraySet<String> modifiedPackages = new ArraySet<>();
|
||||||
|
|
||||||
mPm.executeWithConsistentComputer(computer -> {
|
final boolean[] canSuspend = suspended
|
||||||
final boolean[] canSuspend = suspended
|
? canSuspendPackageForUser(computer, packageNames, userId, callingUid) : null;
|
||||||
? canSuspendPackageForUser(computer, packageNames, userId, callingUid) : null;
|
for (int i = 0; i < packageNames.length; i++) {
|
||||||
for (int i = 0; i < packageNames.length; i++) {
|
final String packageName = packageNames[i];
|
||||||
final String packageName = packageNames[i];
|
if (callingPackage.equals(packageName)) {
|
||||||
if (callingPackage.equals(packageName)) {
|
Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
|
||||||
Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
|
+ (suspended ? "" : "un") + "suspend itself. Ignoring");
|
||||||
+ (suspended ? "" : "un") + "suspend itself. Ignoring");
|
unmodifiablePackages.add(packageName);
|
||||||
unmodifiablePackages.add(packageName);
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
final PackageStateInternal packageState =
|
||||||
final PackageStateInternal packageState =
|
computer.getPackageStateInternal(packageName);
|
||||||
computer.getPackageStateInternal(packageName);
|
if (packageState == null
|
||||||
if (packageState == null
|
|| computer.shouldFilterApplication(packageState, callingUid, userId)) {
|
||||||
|| computer.shouldFilterApplication(packageState, callingUid, userId)) {
|
Slog.w(TAG, "Could not find package setting for package: " + packageName
|
||||||
Slog.w(TAG, "Could not find package setting for package: " + packageName
|
+ ". Skipping suspending/un-suspending.");
|
||||||
+ ". Skipping suspending/un-suspending.");
|
unmodifiablePackages.add(packageName);
|
||||||
unmodifiablePackages.add(packageName);
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
if (canSuspend != null && !canSuspend[i]) {
|
||||||
if (canSuspend != null && !canSuspend[i]) {
|
unmodifiablePackages.add(packageName);
|
||||||
unmodifiablePackages.add(packageName);
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final WatchedArrayMap<String, SuspendParams> suspendParamsMap =
|
final WatchedArrayMap<String, SuspendParams> suspendParamsMap =
|
||||||
packageState.getUserStateOrDefault(userId).getSuspendParams();
|
packageState.getUserStateOrDefault(userId).getSuspendParams();
|
||||||
if (suspended) {
|
if (suspended) {
|
||||||
if (suspendParamsMap != null && suspendParamsMap.containsKey(packageName)) {
|
if (suspendParamsMap != null && suspendParamsMap.containsKey(packageName)) {
|
||||||
final SuspendParams suspendParams = suspendParamsMap.get(packageName);
|
final SuspendParams suspendParams = suspendParamsMap.get(packageName);
|
||||||
// Skip if there's no changes
|
// Skip if there's no changes
|
||||||
if (suspendParams != null
|
if (suspendParams != null
|
||||||
&& Objects.equals(suspendParams.getDialogInfo(), dialogInfo)
|
&& Objects.equals(suspendParams.getDialogInfo(), dialogInfo)
|
||||||
&& Objects.equals(suspendParams.getAppExtras(), appExtras)
|
&& Objects.equals(suspendParams.getAppExtras(), appExtras)
|
||||||
&& Objects.equals(suspendParams.getLauncherExtras(),
|
&& Objects.equals(suspendParams.getLauncherExtras(),
|
||||||
launcherExtras)) {
|
launcherExtras)) {
|
||||||
// Carried over API behavior, must notify change even if no change
|
// Carried over API behavior, must notify change even if no change
|
||||||
changedPackagesList.add(packageName);
|
changedPackagesList.add(packageName);
|
||||||
changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If size one, the package will be unsuspended from this call
|
|
||||||
boolean packageUnsuspended =
|
|
||||||
!suspended && CollectionUtils.size(suspendParamsMap) <= 1;
|
|
||||||
if (suspended || packageUnsuspended) {
|
|
||||||
changedPackagesList.add(packageName);
|
|
||||||
changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
modifiedPackages.add(packageName);
|
|
||||||
modifiedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// If size one, the package will be unsuspended from this call
|
||||||
|
boolean packageUnsuspended =
|
||||||
|
!suspended && CollectionUtils.size(suspendParamsMap) <= 1;
|
||||||
|
if (suspended || packageUnsuspended) {
|
||||||
|
changedPackagesList.add(packageName);
|
||||||
|
changedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
modifiedPackages.add(packageName);
|
||||||
|
modifiedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
||||||
|
}
|
||||||
|
|
||||||
mPm.commitPackageStateMutation(null, mutator -> {
|
mPm.commitPackageStateMutation(null, mutator -> {
|
||||||
final int size = modifiedPackages.size();
|
final int size = modifiedPackages.size();
|
||||||
@@ -218,29 +217,27 @@ public final class SuspendPackageHelper {
|
|||||||
* @return The names of packages which are Unsuspendable.
|
* @return The names of packages which are Unsuspendable.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
String[] getUnsuspendablePackagesForUser(@NonNull String[] packageNames, int userId,
|
String[] getUnsuspendablePackagesForUser(@NonNull Computer computer,
|
||||||
int callingUid) {
|
@NonNull String[] packageNames, @UserIdInt int userId, int callingUid) {
|
||||||
if (!isSuspendAllowedForUser(userId, callingUid)) {
|
if (!isSuspendAllowedForUser(userId, callingUid)) {
|
||||||
Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
|
Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
|
||||||
return packageNames;
|
return packageNames;
|
||||||
}
|
}
|
||||||
final ArraySet<String> unactionablePackages = new ArraySet<>();
|
final ArraySet<String> unactionablePackages = new ArraySet<>();
|
||||||
mPm.executeWithConsistentComputer(computer -> {
|
final boolean[] canSuspend = canSuspendPackageForUser(computer, packageNames, userId,
|
||||||
final boolean[] canSuspend = canSuspendPackageForUser(computer, packageNames, userId,
|
callingUid);
|
||||||
callingUid);
|
for (int i = 0; i < packageNames.length; i++) {
|
||||||
for (int i = 0; i < packageNames.length; i++) {
|
if (!canSuspend[i]) {
|
||||||
if (!canSuspend[i]) {
|
unactionablePackages.add(packageNames[i]);
|
||||||
unactionablePackages.add(packageNames[i]);
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final PackageStateInternal packageState =
|
|
||||||
computer.getPackageStateFiltered(packageNames[i], callingUid, userId);
|
|
||||||
if (packageState == null) {
|
|
||||||
Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
|
|
||||||
unactionablePackages.add(packageNames[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
final PackageStateInternal packageState =
|
||||||
|
computer.getPackageStateFiltered(packageNames[i], callingUid, userId);
|
||||||
|
if (packageState == null) {
|
||||||
|
Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
|
||||||
|
unactionablePackages.add(packageNames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
return unactionablePackages.toArray(new String[unactionablePackages.size()]);
|
return unactionablePackages.toArray(new String[unactionablePackages.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,45 +279,44 @@ public final class SuspendPackageHelper {
|
|||||||
* suspensions will be removed.
|
* suspensions will be removed.
|
||||||
* @param userId The user for which the changes are taking place.
|
* @param userId The user for which the changes are taking place.
|
||||||
*/
|
*/
|
||||||
void removeSuspensionsBySuspendingPackage(@NonNull String[] packagesToChange,
|
void removeSuspensionsBySuspendingPackage(@NonNull Computer computer,
|
||||||
|
@NonNull String[] packagesToChange,
|
||||||
@NonNull Predicate<String> suspendingPackagePredicate, int userId) {
|
@NonNull Predicate<String> suspendingPackagePredicate, int userId) {
|
||||||
final List<String> unsuspendedPackages = new ArrayList<>();
|
final List<String> unsuspendedPackages = new ArrayList<>();
|
||||||
final IntArray unsuspendedUids = new IntArray();
|
final IntArray unsuspendedUids = new IntArray();
|
||||||
final ArrayMap<String, ArraySet<String>> pkgToSuspendingPkgsToCommit = new ArrayMap<>();
|
final ArrayMap<String, ArraySet<String>> pkgToSuspendingPkgsToCommit = new ArrayMap<>();
|
||||||
mPm.executeWithConsistentComputer(computer -> {
|
for (String packageName : packagesToChange) {
|
||||||
for (String packageName : packagesToChange) {
|
final PackageStateInternal packageState =
|
||||||
final PackageStateInternal packageState =
|
computer.getPackageStateInternal(packageName);
|
||||||
computer.getPackageStateInternal(packageName);
|
final PackageUserStateInternal packageUserState = packageState == null
|
||||||
final PackageUserStateInternal packageUserState = packageState == null
|
? null : packageState.getUserStateOrDefault(userId);
|
||||||
? null : packageState.getUserStateOrDefault(userId);
|
if (packageUserState == null || !packageUserState.isSuspended()) {
|
||||||
if (packageUserState == null || !packageUserState.isSuspended()) {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
WatchedArrayMap<String, SuspendParams> suspendParamsMap =
|
WatchedArrayMap<String, SuspendParams> suspendParamsMap =
|
||||||
packageUserState.getSuspendParams();
|
packageUserState.getSuspendParams();
|
||||||
int countRemoved = 0;
|
int countRemoved = 0;
|
||||||
for (int index = 0; index < suspendParamsMap.size(); index++) {
|
for (int index = 0; index < suspendParamsMap.size(); index++) {
|
||||||
String suspendingPackage = suspendParamsMap.keyAt(index);
|
String suspendingPackage = suspendParamsMap.keyAt(index);
|
||||||
if (suspendingPackagePredicate.test(suspendingPackage)) {
|
if (suspendingPackagePredicate.test(suspendingPackage)) {
|
||||||
ArraySet<String> suspendingPkgsToCommit =
|
ArraySet<String> suspendingPkgsToCommit =
|
||||||
pkgToSuspendingPkgsToCommit.get(packageName);
|
pkgToSuspendingPkgsToCommit.get(packageName);
|
||||||
if (suspendingPkgsToCommit == null) {
|
if (suspendingPkgsToCommit == null) {
|
||||||
suspendingPkgsToCommit = new ArraySet<>();
|
suspendingPkgsToCommit = new ArraySet<>();
|
||||||
pkgToSuspendingPkgsToCommit.put(packageName, suspendingPkgsToCommit);
|
pkgToSuspendingPkgsToCommit.put(packageName, suspendingPkgsToCommit);
|
||||||
}
|
|
||||||
suspendingPkgsToCommit.add(suspendingPackage);
|
|
||||||
countRemoved++;
|
|
||||||
}
|
}
|
||||||
}
|
suspendingPkgsToCommit.add(suspendingPackage);
|
||||||
|
countRemoved++;
|
||||||
// Everything would be removed and package unsuspended
|
|
||||||
if (countRemoved == suspendParamsMap.size()) {
|
|
||||||
unsuspendedPackages.add(packageState.getPackageName());
|
|
||||||
unsuspendedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// Everything would be removed and package unsuspended
|
||||||
|
if (countRemoved == suspendParamsMap.size()) {
|
||||||
|
unsuspendedPackages.add(packageState.getPackageName());
|
||||||
|
unsuspendedUids.add(UserHandle.getUid(userId, packageState.getAppId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mPm.commitPackageStateMutation(null, mutator -> {
|
mPm.commitPackageStateMutation(null, mutator -> {
|
||||||
for (int mapIndex = 0; mapIndex < pkgToSuspendingPkgsToCommit.size(); mapIndex++) {
|
for (int mapIndex = 0; mapIndex < pkgToSuspendingPkgsToCommit.size(); mapIndex++) {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.util.PackageUtils;
|
|||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
import com.android.internal.util.CollectionUtils;
|
import com.android.internal.util.CollectionUtils;
|
||||||
|
import com.android.server.pm.Computer;
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
||||||
import com.android.server.pm.pkg.PackageStateInternal;
|
import com.android.server.pm.pkg.PackageStateInternal;
|
||||||
import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState;
|
import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState;
|
||||||
@@ -38,7 +39,6 @@ import com.android.server.pm.verify.domain.models.DomainVerificationStateMap;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
@SuppressWarnings("PointlessBooleanExpression")
|
@SuppressWarnings("PointlessBooleanExpression")
|
||||||
public class DomainVerificationDebug {
|
public class DomainVerificationDebug {
|
||||||
@@ -62,8 +62,7 @@ public class DomainVerificationDebug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void printState(@NonNull IndentingPrintWriter writer, @Nullable String packageName,
|
public void printState(@NonNull IndentingPrintWriter writer, @Nullable String packageName,
|
||||||
@Nullable @UserIdInt Integer userId,
|
@Nullable @UserIdInt Integer userId, @NonNull Computer snapshot,
|
||||||
@NonNull Function<String, PackageStateInternal> pkgSettingFunction,
|
|
||||||
@NonNull DomainVerificationStateMap<DomainVerificationPkgState> stateMap)
|
@NonNull DomainVerificationStateMap<DomainVerificationPkgState> stateMap)
|
||||||
throws NameNotFoundException {
|
throws NameNotFoundException {
|
||||||
ArrayMap<String, Integer> reusedMap = new ArrayMap<>();
|
ArrayMap<String, Integer> reusedMap = new ArrayMap<>();
|
||||||
@@ -74,7 +73,7 @@ public class DomainVerificationDebug {
|
|||||||
for (int index = 0; index < size; index++) {
|
for (int index = 0; index < size; index++) {
|
||||||
DomainVerificationPkgState pkgState = stateMap.valueAt(index);
|
DomainVerificationPkgState pkgState = stateMap.valueAt(index);
|
||||||
String pkgName = pkgState.getPackageName();
|
String pkgName = pkgState.getPackageName();
|
||||||
PackageStateInternal pkgSetting = pkgSettingFunction.apply(pkgName);
|
PackageStateInternal pkgSetting = snapshot.getPackageStateInternal(pkgName);
|
||||||
if (pkgSetting == null || pkgSetting.getPkg() == null) {
|
if (pkgSetting == null || pkgSetting.getPkg() == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -90,7 +89,7 @@ public class DomainVerificationDebug {
|
|||||||
throw DomainVerificationUtils.throwPackageUnavailable(packageName);
|
throw DomainVerificationUtils.throwPackageUnavailable(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageStateInternal pkgSetting = pkgSettingFunction.apply(packageName);
|
PackageStateInternal pkgSetting = snapshot.getPackageStateInternal(packageName);
|
||||||
if (pkgSetting == null || pkgSetting.getPkg() == null) {
|
if (pkgSetting == null || pkgSetting.getPkg() == null) {
|
||||||
throw DomainVerificationUtils.throwPackageUnavailable(packageName);
|
throw DomainVerificationUtils.throwPackageUnavailable(packageName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import android.content.Intent;
|
|||||||
import android.content.pm.IntentFilterVerificationInfo;
|
import android.content.pm.IntentFilterVerificationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.pm.PackageSettingsSnapshotProvider;
|
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.pm.verify.domain.DomainVerificationInfo;
|
import android.content.pm.verify.domain.DomainVerificationInfo;
|
||||||
import android.content.pm.verify.domain.DomainVerificationManager;
|
import android.content.pm.verify.domain.DomainVerificationManager;
|
||||||
@@ -37,7 +36,7 @@ import android.util.Pair;
|
|||||||
import android.util.TypedXmlPullParser;
|
import android.util.TypedXmlPullParser;
|
||||||
import android.util.TypedXmlSerializer;
|
import android.util.TypedXmlSerializer;
|
||||||
|
|
||||||
import com.android.server.pm.PackageManagerService;
|
import com.android.server.pm.Computer;
|
||||||
import com.android.server.pm.PackageSetting;
|
import com.android.server.pm.PackageSetting;
|
||||||
import com.android.server.pm.Settings;
|
import com.android.server.pm.Settings;
|
||||||
import com.android.server.pm.pkg.PackageStateInternal;
|
import com.android.server.pm.pkg.PackageStateInternal;
|
||||||
@@ -227,14 +226,14 @@ public interface DomainVerificationManagerInternal {
|
|||||||
* assumed nothing has changed since the device rebooted.
|
* assumed nothing has changed since the device rebooted.
|
||||||
* <p>
|
* <p>
|
||||||
* If this is a new install, state will be restored from a previous call to {@link
|
* If this is a new install, state will be restored from a previous call to {@link
|
||||||
* #restoreSettings(TypedXmlPullParser)}, or a new one will be generated. In either case, a
|
* #restoreSettings(Computer, TypedXmlPullParser)}, or a new one will be generated. In either case, a
|
||||||
* broadcast will be sent to the domain verification agent so it may re-run any verification
|
* broadcast will be sent to the domain verification agent so it may re-run any verification
|
||||||
* logic for the newly associated domains.
|
* logic for the newly associated domains.
|
||||||
* <p>
|
* <p>
|
||||||
* This will mutate internal {@link DomainVerificationPkgState} and so will hold the internal
|
* This will mutate internal {@link DomainVerificationPkgState} and so will hold the internal
|
||||||
* lock. This should never be called from within the domain verification classes themselves.
|
* lock. This should never be called from within the domain verification classes themselves.
|
||||||
* <p>
|
* <p>
|
||||||
* This will NOT call {@link #writeSettings(TypedXmlSerializer, boolean, int)}. That must be
|
* This will NOT call {@link #writeSettings(Computer, TypedXmlSerializer, boolean, int)}. That must be
|
||||||
* handled by the caller.
|
* handled by the caller.
|
||||||
*/
|
*/
|
||||||
void addPackage(@NonNull PackageStateInternal newPkgSetting);
|
void addPackage(@NonNull PackageStateInternal newPkgSetting);
|
||||||
@@ -249,7 +248,7 @@ public interface DomainVerificationManagerInternal {
|
|||||||
* This will mutate internal {@link DomainVerificationPkgState} and so will hold the internal
|
* This will mutate internal {@link DomainVerificationPkgState} and so will hold the internal
|
||||||
* lock. This should never be called from within the domain verification classes themselves.
|
* lock. This should never be called from within the domain verification classes themselves.
|
||||||
* <p>
|
* <p>
|
||||||
* This will NOT call {@link #writeSettings(TypedXmlSerializer, boolean, int)}. That must be
|
* This will NOT call {@link #writeSettings(Computer, TypedXmlSerializer, boolean, int)}. That must be
|
||||||
* handled by the caller.
|
* handled by the caller.
|
||||||
*/
|
*/
|
||||||
void migrateState(@NonNull PackageStateInternal oldPkgSetting,
|
void migrateState(@NonNull PackageStateInternal oldPkgSetting,
|
||||||
@@ -259,24 +258,24 @@ public interface DomainVerificationManagerInternal {
|
|||||||
* Serializes the entire internal state. This is equivalent to a full backup of the existing
|
* Serializes the entire internal state. This is equivalent to a full backup of the existing
|
||||||
* verification state. This write includes legacy state, as a sibling tag the modern state.
|
* verification state. This write includes legacy state, as a sibling tag the modern state.
|
||||||
*
|
*
|
||||||
|
* @param snapshot
|
||||||
* @param includeSignatures Whether to include the package signatures in the output, mainly
|
* @param includeSignatures Whether to include the package signatures in the output, mainly
|
||||||
* used for backing up the user settings and ensuring they're
|
* used for backing up the user settings and ensuring they're
|
||||||
* re-attached to the same package.
|
* re-attached to the same package.
|
||||||
* @param userId The user to write out. Supports {@link UserHandle#USER_ALL} if all users
|
* @param userId The user to write out. Supports {@link UserHandle#USER_ALL} if all users
|
||||||
* should be written.
|
|
||||||
*/
|
*/
|
||||||
void writeSettings(@NonNull TypedXmlSerializer serializer, boolean includeSignatures,
|
void writeSettings(@NonNull Computer snapshot, @NonNull TypedXmlSerializer serializer,
|
||||||
@UserIdInt int userId) throws IOException;
|
boolean includeSignatures, @UserIdInt int userId) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read back a list of {@link DomainVerificationPkgState}s previously written by {@link
|
* Read back a list of {@link DomainVerificationPkgState}s previously written by {@link
|
||||||
* #writeSettings(TypedXmlSerializer, boolean, int)}. Assumes that the
|
* #writeSettings(Computer, TypedXmlSerializer, boolean, int)}. Assumes that the
|
||||||
* {@link DomainVerificationPersistence#TAG_DOMAIN_VERIFICATIONS} tag has already been entered.
|
* {@link DomainVerificationPersistence#TAG_DOMAIN_VERIFICATIONS} tag has already been entered.
|
||||||
* <p>
|
* <p>
|
||||||
* This is expected to only be used to re-attach states for packages already known to be on the
|
* This is expected to only be used to re-attach states for packages already known to be on the
|
||||||
* device. If restoring from a backup, use {@link #restoreSettings(TypedXmlPullParser)}.
|
* device. If restoring from a backup, use {@link #restoreSettings(Computer, TypedXmlPullParser)}.
|
||||||
*/
|
*/
|
||||||
void readSettings(@NonNull TypedXmlPullParser parser)
|
void readSettings(@NonNull Computer snapshot, @NonNull TypedXmlPullParser parser)
|
||||||
throws IOException, XmlPullParserException;
|
throws IOException, XmlPullParserException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -306,7 +305,7 @@ public interface DomainVerificationManagerInternal {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore a list of {@link DomainVerificationPkgState}s previously written by {@link
|
* Restore a list of {@link DomainVerificationPkgState}s previously written by {@link
|
||||||
* #writeSettings(TypedXmlSerializer, boolean, int)}. Assumes that the
|
* #writeSettings(Computer, TypedXmlSerializer, boolean, int)}. Assumes that the
|
||||||
* {@link DomainVerificationPersistence#TAG_DOMAIN_VERIFICATIONS}
|
* {@link DomainVerificationPersistence#TAG_DOMAIN_VERIFICATIONS}
|
||||||
* tag has already been entered.
|
* tag has already been entered.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -321,7 +320,7 @@ public interface DomainVerificationManagerInternal {
|
|||||||
* TODO(b/170746586): Figure out how to verify that package signatures match at snapshot time
|
* TODO(b/170746586): Figure out how to verify that package signatures match at snapshot time
|
||||||
* and restore time.
|
* and restore time.
|
||||||
*/
|
*/
|
||||||
void restoreSettings(@NonNull TypedXmlPullParser parser)
|
void restoreSettings(@NonNull Computer snapshot, @NonNull TypedXmlPullParser parser)
|
||||||
throws IOException, XmlPullParserException;
|
throws IOException, XmlPullParserException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -349,17 +348,14 @@ public interface DomainVerificationManagerInternal {
|
|||||||
/**
|
/**
|
||||||
* Print the verification state and user selection state of a package.
|
* Print the verification state and user selection state of a package.
|
||||||
*
|
*
|
||||||
|
* @param snapshot
|
||||||
* @param packageName the package whose state to change, or all packages if none is
|
* @param packageName the package whose state to change, or all packages if none is
|
||||||
* specified
|
* specified
|
||||||
* @param userId the specific user to print, or null to skip printing user selection
|
* @param userId the specific user to print, or null to skip printing user selection
|
||||||
* states, supports {@link android.os.UserHandle#USER_ALL}
|
* states, supports {@link UserHandle#USER_ALL}
|
||||||
* @param pkgSettingFunction the method by which to retrieve package data; if this is called
|
|
||||||
* from {@link PackageManagerService}, it is expected to pass in the
|
|
||||||
* snapshot of {@link PackageStateInternal} objects
|
|
||||||
*/
|
*/
|
||||||
void printState(@NonNull IndentingPrintWriter writer, @Nullable String packageName,
|
void printState(@NonNull Computer snapshot, @NonNull IndentingPrintWriter writer,
|
||||||
@Nullable @UserIdInt Integer userId,
|
@Nullable String packageName, @Nullable @UserIdInt Integer userId)
|
||||||
@NonNull Function<String, PackageStateInternal> pkgSettingFunction)
|
|
||||||
throws NameNotFoundException;
|
throws NameNotFoundException;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -406,12 +402,11 @@ public interface DomainVerificationManagerInternal {
|
|||||||
@NonNull Set<String> domains, int state) throws NameNotFoundException;
|
@NonNull Set<String> domains, int state) throws NameNotFoundException;
|
||||||
|
|
||||||
|
|
||||||
interface Connection extends DomainVerificationEnforcer.Callback,
|
interface Connection extends DomainVerificationEnforcer.Callback {
|
||||||
PackageSettingsSnapshotProvider {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify that a settings change has been made and that eventually
|
* Notify that a settings change has been made and that eventually
|
||||||
* {@link #writeSettings(TypedXmlSerializer, boolean, int)} should be invoked by the parent.
|
* {@link #writeSettings(Computer, TypedXmlSerializer, boolean, int)} should be invoked by the parent.
|
||||||
*/
|
*/
|
||||||
void scheduleWriteSettings();
|
void scheduleWriteSettings();
|
||||||
|
|
||||||
@@ -433,5 +428,8 @@ public interface DomainVerificationManagerInternal {
|
|||||||
|
|
||||||
@UserIdInt
|
@UserIdInt
|
||||||
int[] getAllUserIds();
|
int[] getAllUserIds();
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
Computer snapshot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,7 @@ import android.util.TypedXmlSerializer;
|
|||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.server.pm.Computer;
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
||||||
import com.android.server.pm.pkg.PackageStateInternal;
|
import com.android.server.pm.pkg.PackageStateInternal;
|
||||||
import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState;
|
import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState;
|
||||||
@@ -101,8 +102,7 @@ class DomainVerificationSettings {
|
|||||||
*/
|
*/
|
||||||
public void readSettings(@NonNull TypedXmlPullParser parser,
|
public void readSettings(@NonNull TypedXmlPullParser parser,
|
||||||
@NonNull DomainVerificationStateMap<DomainVerificationPkgState> liveState,
|
@NonNull DomainVerificationStateMap<DomainVerificationPkgState> liveState,
|
||||||
@NonNull Function<String, PackageStateInternal> pkgSettingFunction)
|
@NonNull Computer snapshot) throws IOException, XmlPullParserException {
|
||||||
throws IOException, XmlPullParserException {
|
|
||||||
DomainVerificationPersistence.ReadResult result =
|
DomainVerificationPersistence.ReadResult result =
|
||||||
DomainVerificationPersistence.readFromXml(parser);
|
DomainVerificationPersistence.readFromXml(parser);
|
||||||
ArrayMap<String, DomainVerificationPkgState> active = result.active;
|
ArrayMap<String, DomainVerificationPkgState> active = result.active;
|
||||||
@@ -118,7 +118,7 @@ class DomainVerificationSettings {
|
|||||||
// This branch should never be possible. Settings should be read from disk
|
// This branch should never be possible. Settings should be read from disk
|
||||||
// before any states are attached. But just in case, handle it.
|
// before any states are attached. But just in case, handle it.
|
||||||
if (!existingState.getId().equals(pkgState.getId())) {
|
if (!existingState.getId().equals(pkgState.getId())) {
|
||||||
mergePkgState(existingState, pkgState, pkgSettingFunction);
|
mergePkgState(existingState, pkgState, snapshot);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mPendingPkgStates.put(pkgName, pkgState);
|
mPendingPkgStates.put(pkgName, pkgState);
|
||||||
@@ -139,8 +139,7 @@ class DomainVerificationSettings {
|
|||||||
*/
|
*/
|
||||||
public void restoreSettings(@NonNull TypedXmlPullParser parser,
|
public void restoreSettings(@NonNull TypedXmlPullParser parser,
|
||||||
@NonNull DomainVerificationStateMap<DomainVerificationPkgState> liveState,
|
@NonNull DomainVerificationStateMap<DomainVerificationPkgState> liveState,
|
||||||
@NonNull Function<String, PackageStateInternal> pkgSettingFunction)
|
@NonNull Computer snapshot) throws IOException, XmlPullParserException {
|
||||||
throws IOException, XmlPullParserException {
|
|
||||||
// TODO(b/170746586): Restoration assumes user IDs match, which is probably not the case on
|
// TODO(b/170746586): Restoration assumes user IDs match, which is probably not the case on
|
||||||
// a new device.
|
// a new device.
|
||||||
|
|
||||||
@@ -166,7 +165,7 @@ class DomainVerificationSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (existingState != null) {
|
if (existingState != null) {
|
||||||
mergePkgState(existingState, newState, pkgSettingFunction);
|
mergePkgState(existingState, newState, snapshot);
|
||||||
} else {
|
} else {
|
||||||
// If there's no existing state, that means the new state has to be transformed
|
// If there's no existing state, that means the new state has to be transformed
|
||||||
// in preparation for attaching to brand new package that may eventually be
|
// in preparation for attaching to brand new package that may eventually be
|
||||||
@@ -216,9 +215,9 @@ class DomainVerificationSettings {
|
|||||||
*/
|
*/
|
||||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
|
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
|
||||||
public void mergePkgState(@NonNull DomainVerificationPkgState oldState,
|
public void mergePkgState(@NonNull DomainVerificationPkgState oldState,
|
||||||
@NonNull DomainVerificationPkgState newState,
|
@NonNull DomainVerificationPkgState newState, @NonNull Computer snapshot) {
|
||||||
@NonNull Function<String, PackageStateInternal> pkgSettingFunction) {
|
PackageStateInternal pkgSetting =
|
||||||
PackageStateInternal pkgSetting = pkgSettingFunction.apply(oldState.getPackageName());
|
snapshot.getPackageStateInternal(oldState.getPackageName());
|
||||||
AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
|
AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
|
||||||
Set<String> validDomains = pkg == null
|
Set<String> validDomains = pkg == null
|
||||||
? Collections.emptySet() : mCollector.collectValidAutoVerifyDomains(pkg);
|
? Collections.emptySet() : mCollector.collectValidAutoVerifyDomains(pkg);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.util.ArraySet;
|
|||||||
import android.util.IndentingPrintWriter;
|
import android.util.IndentingPrintWriter;
|
||||||
|
|
||||||
import com.android.modules.utils.BasicShellCommandHandler;
|
import com.android.modules.utils.BasicShellCommandHandler;
|
||||||
|
import com.android.server.pm.Computer;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -39,7 +40,6 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class DomainVerificationShell {
|
public class DomainVerificationShell {
|
||||||
|
|
||||||
@@ -599,8 +599,8 @@ public class DomainVerificationShell {
|
|||||||
void verifyPackages(@Nullable List<String> packageNames, boolean reVerify);
|
void verifyPackages(@Nullable List<String> packageNames, boolean reVerify);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DomainVerificationManagerInternal#printState(IndentingPrintWriter, String, Integer,
|
* @see DomainVerificationManagerInternal#printState(Computer, IndentingPrintWriter, String,
|
||||||
* Function)
|
* Integer)
|
||||||
*/
|
*/
|
||||||
void printState(@NonNull IndentingPrintWriter writer, @Nullable String packageName,
|
void printState(@NonNull IndentingPrintWriter writer, @Nullable String packageName,
|
||||||
@Nullable @UserIdInt Integer userId) throws NameNotFoundException;
|
@Nullable @UserIdInt Integer userId) throws NameNotFoundException;
|
||||||
|
|||||||
@@ -265,12 +265,14 @@ class PackageManagerComponentLabelIconOverrideTest {
|
|||||||
assertServiceInitialized() ?: return
|
assertServiceInitialized() ?: return
|
||||||
when (params.result) {
|
when (params.result) {
|
||||||
is Result.Changed, Result.ChangedWithoutNotify -> {
|
is Result.Changed, Result.ChangedWithoutNotify -> {
|
||||||
assertThat(mockPendingBroadcasts.get(userId, params.pkgName) ?: emptyList<String>())
|
assertThat(mockPendingBroadcasts.copiedMap()?.get(userId)?.get(params.pkgName)
|
||||||
|
?: emptyList<String>())
|
||||||
.containsExactly(params.componentName!!.className)
|
.containsExactly(params.componentName!!.className)
|
||||||
.inOrder()
|
.inOrder()
|
||||||
}
|
}
|
||||||
is Result.NotChanged, is Result.Exception -> {
|
is Result.NotChanged, is Result.Exception -> {
|
||||||
assertThat(mockPendingBroadcasts.get(userId, params.pkgName)).isNull()
|
assertThat(mockPendingBroadcasts.copiedMap()?.get(userId)?.get(params.pkgName))
|
||||||
|
.isNull()
|
||||||
}
|
}
|
||||||
}.run { /*exhaust*/ }
|
}.run { /*exhaust*/ }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.SigningDetails
|
import android.content.pm.SigningDetails
|
||||||
import com.android.server.pm.pkg.component.ParsedActivityImpl
|
|
||||||
import com.android.server.pm.pkg.component.ParsedIntentInfoImpl
|
|
||||||
import android.content.pm.verify.domain.DomainVerificationManager
|
import android.content.pm.verify.domain.DomainVerificationManager
|
||||||
import android.content.pm.verify.domain.DomainVerificationState
|
import android.content.pm.verify.domain.DomainVerificationState
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@@ -30,10 +28,12 @@ import android.util.ArraySet
|
|||||||
import android.util.IndentingPrintWriter
|
import android.util.IndentingPrintWriter
|
||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import com.android.server.pm.Computer
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackage
|
import com.android.server.pm.parsing.pkg.AndroidPackage
|
||||||
import com.android.server.pm.pkg.PackageStateInternal
|
import com.android.server.pm.pkg.PackageStateInternal
|
||||||
import com.android.server.pm.pkg.PackageUserStateInternal
|
import com.android.server.pm.pkg.PackageUserStateInternal
|
||||||
import com.android.server.pm.test.verify.domain.DomainVerificationTestUtils.mockPackageStates
|
import com.android.server.pm.pkg.component.ParsedActivityImpl
|
||||||
|
import com.android.server.pm.pkg.component.ParsedIntentInfoImpl
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationEnforcer
|
import com.android.server.pm.verify.domain.DomainVerificationEnforcer
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
|
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationService
|
import com.android.server.pm.verify.domain.DomainVerificationService
|
||||||
@@ -100,11 +100,15 @@ class DomainVerificationEnforcerTest {
|
|||||||
mockThrowOnUnmocked {
|
mockThrowOnUnmocked {
|
||||||
whenever(callingUid) { callingUidInt.get() }
|
whenever(callingUid) { callingUidInt.get() }
|
||||||
whenever(callingUserId) { callingUserIdInt.get() }
|
whenever(callingUserId) { callingUserIdInt.get() }
|
||||||
mockPackageStates {
|
whenever(snapshot()) {
|
||||||
when (it) {
|
mockThrowOnUnmocked {
|
||||||
VISIBLE_PKG -> visiblePkgState
|
whenever(getPackageStateInternal(anyString())) {
|
||||||
INVISIBLE_PKG -> invisiblePkgState
|
when (getArgument<String>(0)) {
|
||||||
else -> null
|
VISIBLE_PKG -> visiblePkgState
|
||||||
|
INVISIBLE_PKG -> invisiblePkgState
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
whenever(schedule(anyInt(), any()))
|
whenever(schedule(anyInt(), any()))
|
||||||
@@ -211,9 +215,8 @@ class DomainVerificationEnforcerTest {
|
|||||||
printState(mock(IndentingPrintWriter::class.java), null, null)
|
printState(mock(IndentingPrintWriter::class.java), null, null)
|
||||||
},
|
},
|
||||||
service(Type.QUERENT, "printStateInternal") {
|
service(Type.QUERENT, "printStateInternal") {
|
||||||
printState(mock(IndentingPrintWriter::class.java), null, null) {
|
printState(mock(Computer::class.java), mock(IndentingPrintWriter::class.java),
|
||||||
mockPkgState(it, UUID.randomUUID())
|
null, null)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
service(Type.VERIFIER, "setStatus") {
|
service(Type.VERIFIER, "setStatus") {
|
||||||
setDomainVerificationStatus(
|
setDomainVerificationStatus(
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ package com.android.server.pm.test.verify.domain
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import com.android.server.pm.pkg.component.ParsedActivityImpl
|
|
||||||
import com.android.server.pm.pkg.component.ParsedIntentInfoImpl
|
|
||||||
import com.android.server.pm.pkg.PackageUserStateInternal
|
|
||||||
import android.content.pm.verify.domain.DomainOwner
|
import android.content.pm.verify.domain.DomainOwner
|
||||||
import android.content.pm.verify.domain.DomainVerificationInfo
|
import android.content.pm.verify.domain.DomainVerificationInfo
|
||||||
import android.content.pm.verify.domain.DomainVerificationManager
|
import android.content.pm.verify.domain.DomainVerificationManager
|
||||||
@@ -34,7 +31,9 @@ import android.util.ArraySet
|
|||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackage
|
import com.android.server.pm.parsing.pkg.AndroidPackage
|
||||||
import com.android.server.pm.pkg.PackageStateInternal
|
import com.android.server.pm.pkg.PackageStateInternal
|
||||||
import com.android.server.pm.test.verify.domain.DomainVerificationTestUtils.mockPackageStates
|
import com.android.server.pm.pkg.PackageUserStateInternal
|
||||||
|
import com.android.server.pm.pkg.component.ParsedActivityImpl
|
||||||
|
import com.android.server.pm.pkg.component.ParsedIntentInfoImpl
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationManagerStub
|
import com.android.server.pm.verify.domain.DomainVerificationManagerStub
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationService
|
import com.android.server.pm.verify.domain.DomainVerificationService
|
||||||
import com.android.server.testutils.mockThrowOnUnmocked
|
import com.android.server.testutils.mockThrowOnUnmocked
|
||||||
@@ -502,8 +501,12 @@ class DomainVerificationManagerApiTest {
|
|||||||
whenever(callingUid) { Process.ROOT_UID }
|
whenever(callingUid) { Process.ROOT_UID }
|
||||||
whenever(callingUserId) { 0 }
|
whenever(callingUserId) { 0 }
|
||||||
|
|
||||||
mockPackageStates {
|
whenever(snapshot()) {
|
||||||
pkgStateFunction(it)
|
mockThrowOnUnmocked {
|
||||||
|
whenever(getPackageStateInternal(anyString())) {
|
||||||
|
pkgStateFunction(getArgument(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ import android.content.Intent
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.Signature
|
import android.content.pm.Signature
|
||||||
import android.content.pm.SigningDetails
|
import android.content.pm.SigningDetails
|
||||||
import com.android.server.pm.pkg.component.ParsedActivityImpl
|
|
||||||
import com.android.server.pm.pkg.component.ParsedIntentInfoImpl
|
|
||||||
import com.android.server.pm.pkg.PackageUserStateInternal
|
|
||||||
import android.content.pm.verify.domain.DomainOwner
|
import android.content.pm.verify.domain.DomainOwner
|
||||||
import android.content.pm.verify.domain.DomainVerificationInfo.STATE_MODIFIABLE_VERIFIED
|
import android.content.pm.verify.domain.DomainVerificationInfo.STATE_MODIFIABLE_VERIFIED
|
||||||
import android.content.pm.verify.domain.DomainVerificationInfo.STATE_NO_RESPONSE
|
import android.content.pm.verify.domain.DomainVerificationInfo.STATE_NO_RESPONSE
|
||||||
@@ -39,9 +36,12 @@ import android.os.Process
|
|||||||
import android.util.ArraySet
|
import android.util.ArraySet
|
||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import android.util.Xml
|
import android.util.Xml
|
||||||
|
import com.android.server.pm.Computer
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackage
|
import com.android.server.pm.parsing.pkg.AndroidPackage
|
||||||
import com.android.server.pm.pkg.PackageStateInternal
|
import com.android.server.pm.pkg.PackageStateInternal
|
||||||
import com.android.server.pm.test.verify.domain.DomainVerificationTestUtils.mockPackageStates
|
import com.android.server.pm.pkg.PackageUserStateInternal
|
||||||
|
import com.android.server.pm.pkg.component.ParsedActivityImpl
|
||||||
|
import com.android.server.pm.pkg.component.ParsedIntentInfoImpl
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationService
|
import com.android.server.pm.verify.domain.DomainVerificationService
|
||||||
import com.android.server.testutils.mock
|
import com.android.server.testutils.mock
|
||||||
import com.android.server.testutils.mockThrowOnUnmocked
|
import com.android.server.testutils.mockThrowOnUnmocked
|
||||||
@@ -194,7 +194,8 @@ class DomainVerificationPackageTest {
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
val service = makeService(pkg1, pkg2)
|
val service = makeService(pkg1, pkg2)
|
||||||
service.restoreSettings(Xml.resolvePullParser(xml.byteInputStream()))
|
val computer = mockComputer(pkg1, pkg2)
|
||||||
|
service.restoreSettings(computer, Xml.resolvePullParser(xml.byteInputStream()))
|
||||||
service.addPackage(pkg1)
|
service.addPackage(pkg1)
|
||||||
val info = service.getInfo(pkg1.packageName)
|
val info = service.getInfo(pkg1.packageName)
|
||||||
assertThat(info.packageName).isEqualTo(pkg1.packageName)
|
assertThat(info.packageName).isEqualTo(pkg1.packageName)
|
||||||
@@ -243,7 +244,8 @@ class DomainVerificationPackageTest {
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
val service = makeService(pkg1, pkg2)
|
val service = makeService(pkg1, pkg2)
|
||||||
service.restoreSettings(Xml.resolvePullParser(xml.byteInputStream()))
|
val computer = mockComputer(pkg1, pkg2)
|
||||||
|
service.restoreSettings(computer, Xml.resolvePullParser(xml.byteInputStream()))
|
||||||
service.addPackage(pkg1)
|
service.addPackage(pkg1)
|
||||||
val info = service.getInfo(pkg1.packageName)
|
val info = service.getInfo(pkg1.packageName)
|
||||||
assertThat(info.packageName).isEqualTo(pkg1.packageName)
|
assertThat(info.packageName).isEqualTo(pkg1.packageName)
|
||||||
@@ -298,8 +300,9 @@ class DomainVerificationPackageTest {
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
val service = makeService(pkg1, pkg2)
|
val service = makeService(pkg1, pkg2)
|
||||||
|
val computer = mockComputer(pkg1, pkg2)
|
||||||
xml.byteInputStream().use {
|
xml.byteInputStream().use {
|
||||||
service.readSettings(Xml.resolvePullParser(it))
|
service.readSettings(computer, Xml.resolvePullParser(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
service.addPackage(pkg1)
|
service.addPackage(pkg1)
|
||||||
@@ -311,8 +314,9 @@ class DomainVerificationPackageTest {
|
|||||||
fun addPackagePendingStripInvalidDomains() {
|
fun addPackagePendingStripInvalidDomains() {
|
||||||
val xml = addPackagePendingOrRestoredWithInvalidDomains()
|
val xml = addPackagePendingOrRestoredWithInvalidDomains()
|
||||||
val service = makeService(pkg1, pkg2)
|
val service = makeService(pkg1, pkg2)
|
||||||
|
val computer = mockComputer(pkg1, pkg2)
|
||||||
xml.byteInputStream().use {
|
xml.byteInputStream().use {
|
||||||
service.readSettings(Xml.resolvePullParser(it))
|
service.readSettings(computer, Xml.resolvePullParser(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
service.addPackage(pkg1)
|
service.addPackage(pkg1)
|
||||||
@@ -334,8 +338,9 @@ class DomainVerificationPackageTest {
|
|||||||
fun addPackageRestoredStripInvalidDomains() {
|
fun addPackageRestoredStripInvalidDomains() {
|
||||||
val xml = addPackagePendingOrRestoredWithInvalidDomains()
|
val xml = addPackagePendingOrRestoredWithInvalidDomains()
|
||||||
val service = makeService(pkg1, pkg2)
|
val service = makeService(pkg1, pkg2)
|
||||||
|
val computer = mockComputer(pkg1, pkg2)
|
||||||
xml.byteInputStream().use {
|
xml.byteInputStream().use {
|
||||||
service.restoreSettings(Xml.resolvePullParser(it))
|
service.restoreSettings(computer, Xml.resolvePullParser(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
service.addPackage(pkg1)
|
service.addPackage(pkg1)
|
||||||
@@ -686,6 +691,7 @@ class DomainVerificationPackageTest {
|
|||||||
val pkg2 = mockPkgState(PKG_TWO, UUID_TWO, SIGNATURE_TWO,
|
val pkg2 = mockPkgState(PKG_TWO, UUID_TWO, SIGNATURE_TWO,
|
||||||
listOf(DOMAIN_1, DOMAIN_2, DOMAIN_3))
|
listOf(DOMAIN_1, DOMAIN_2, DOMAIN_3))
|
||||||
val serviceBefore = makeService(pkg1, pkg2)
|
val serviceBefore = makeService(pkg1, pkg2)
|
||||||
|
val computerBefore = mockComputer(pkg1, pkg2)
|
||||||
serviceBefore.addPackage(pkg1)
|
serviceBefore.addPackage(pkg1)
|
||||||
serviceBefore.addPackage(pkg2)
|
serviceBefore.addPackage(pkg2)
|
||||||
|
|
||||||
@@ -729,16 +735,17 @@ class DomainVerificationPackageTest {
|
|||||||
assertExpectedState(serviceBefore)
|
assertExpectedState(serviceBefore)
|
||||||
|
|
||||||
val backupUser0 = ByteArrayOutputStream().use {
|
val backupUser0 = ByteArrayOutputStream().use {
|
||||||
serviceBefore.writeSettings(Xml.resolveSerializer(it), true, 0)
|
serviceBefore.writeSettings(computerBefore, Xml.resolveSerializer(it), true, 0)
|
||||||
it.toByteArray()
|
it.toByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
val backupUser1 = ByteArrayOutputStream().use {
|
val backupUser1 = ByteArrayOutputStream().use {
|
||||||
serviceBefore.writeSettings(Xml.resolveSerializer(it), true, 10)
|
serviceBefore.writeSettings(computerBefore, Xml.resolveSerializer(it), true, 10)
|
||||||
it.toByteArray()
|
it.toByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
val serviceAfter = makeService(pkg1, pkg2)
|
val serviceAfter = makeService(pkg1, pkg2)
|
||||||
|
val computerAfter = mockComputer(pkg1, pkg2)
|
||||||
serviceAfter.addPackage(pkg1)
|
serviceAfter.addPackage(pkg1)
|
||||||
serviceAfter.addPackage(pkg2)
|
serviceAfter.addPackage(pkg2)
|
||||||
|
|
||||||
@@ -763,7 +770,7 @@ class DomainVerificationPackageTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ByteArrayInputStream(backupUser1).use {
|
ByteArrayInputStream(backupUser1).use {
|
||||||
serviceAfter.restoreSettings(Xml.resolvePullParser(it))
|
serviceAfter.restoreSettings(computerAfter, Xml.resolvePullParser(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert user 1 was restored
|
// Assert user 1 was restored
|
||||||
@@ -800,7 +807,7 @@ class DomainVerificationPackageTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
ByteArrayInputStream(backupUser0).use {
|
ByteArrayInputStream(backupUser0).use {
|
||||||
serviceAfter.restoreSettings(Xml.resolvePullParser(it))
|
serviceAfter.restoreSettings(computerAfter, Xml.resolvePullParser(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
assertExpectedState(serviceAfter)
|
assertExpectedState(serviceAfter)
|
||||||
@@ -848,12 +855,20 @@ class DomainVerificationPackageTest {
|
|||||||
whenever(callingUid) { Process.ROOT_UID }
|
whenever(callingUid) { Process.ROOT_UID }
|
||||||
whenever(callingUserId) { 0 }
|
whenever(callingUserId) { 0 }
|
||||||
|
|
||||||
mockPackageStates {
|
whenever(snapshot()) { mockComputer(pkgStateFunction) }
|
||||||
pkgStateFunction(it)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun mockComputer(vararg pkgStates: PackageStateInternal) =
|
||||||
|
mockComputer { pkgName -> pkgStates.find { pkgName == it.packageName } }
|
||||||
|
|
||||||
|
private fun mockComputer(pkgStateFunction: (String) -> PackageStateInternal? = { null }) =
|
||||||
|
mockThrowOnUnmocked<Computer> {
|
||||||
|
whenever(getPackageStateInternal(anyString())) {
|
||||||
|
pkgStateFunction(getArgument(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun mockPkgState(
|
private fun mockPkgState(
|
||||||
pkgName: String,
|
pkgName: String,
|
||||||
domainSetId: UUID,
|
domainSetId: UUID,
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import android.util.ArraySet
|
|||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackage
|
import com.android.server.pm.parsing.pkg.AndroidPackage
|
||||||
import com.android.server.pm.pkg.PackageStateInternal
|
import com.android.server.pm.pkg.PackageStateInternal
|
||||||
import com.android.server.pm.test.verify.domain.DomainVerificationTestUtils.mockPackageStates
|
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
|
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationService
|
import com.android.server.pm.verify.domain.DomainVerificationService
|
||||||
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy
|
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy
|
||||||
@@ -245,10 +244,14 @@ class DomainVerificationSettingsMutationTest {
|
|||||||
mockThrowOnUnmocked {
|
mockThrowOnUnmocked {
|
||||||
whenever(callingUid) { TEST_UID }
|
whenever(callingUid) { TEST_UID }
|
||||||
whenever(callingUserId) { TEST_USER_ID }
|
whenever(callingUserId) { TEST_USER_ID }
|
||||||
mockPackageStates {
|
whenever(snapshot()) {
|
||||||
when (it) {
|
mockThrowOnUnmocked {
|
||||||
TEST_PKG -> mockPkgState()
|
whenever(getPackageStateInternal(anyString())) {
|
||||||
else -> null
|
when (getArgument<String>(0)) {
|
||||||
|
TEST_PKG -> mockPkgState()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
whenever(schedule(anyInt(), any()))
|
whenever(schedule(anyInt(), any()))
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.test.verify.domain
|
|
||||||
|
|
||||||
import com.android.internal.util.FunctionalUtils
|
|
||||||
import com.android.server.pm.pkg.PackageStateInternal
|
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
|
|
||||||
import com.android.server.testutils.whenever
|
|
||||||
import org.mockito.ArgumentMatchers.any
|
|
||||||
import java.util.function.Consumer
|
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
internal object DomainVerificationTestUtils {
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
fun DomainVerificationManagerInternal.Connection.mockPackageStates(
|
|
||||||
block: (String) -> PackageStateInternal?
|
|
||||||
) {
|
|
||||||
whenever(withPackageSettingsSnapshot(any())) {
|
|
||||||
(arguments[0] as Consumer<Function<String, PackageStateInternal?>>).accept { block(it) }
|
|
||||||
}
|
|
||||||
whenever(withPackageSettingsSnapshotReturning(any())) {
|
|
||||||
(arguments[0] as FunctionalUtils.ThrowingFunction<
|
|
||||||
Function<String, PackageStateInternal?>, *>)
|
|
||||||
.apply { block(it) }
|
|
||||||
}
|
|
||||||
whenever(withPackageSettingsSnapshotThrowing<Exception>(any())) {
|
|
||||||
(arguments[0] as FunctionalUtils.ThrowingCheckedConsumer<
|
|
||||||
Function<String, PackageStateInternal?>, *>)
|
|
||||||
.accept { block(it) }
|
|
||||||
}
|
|
||||||
whenever(withPackageSettingsSnapshotThrowing2<Exception, Exception>(any())) {
|
|
||||||
(arguments[0] as FunctionalUtils.ThrowingChecked2Consumer<
|
|
||||||
Function<String, PackageStateInternal?>, *, *>)
|
|
||||||
.accept { block(it) }
|
|
||||||
}
|
|
||||||
whenever(withPackageSettingsSnapshotReturningThrowing<Any, Exception>(any())) {
|
|
||||||
(arguments[0] as FunctionalUtils.ThrowingCheckedFunction<
|
|
||||||
Function<String, PackageStateInternal?>, *, *>)
|
|
||||||
.apply { block(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -31,7 +31,6 @@ import android.util.SparseArray
|
|||||||
import com.android.server.pm.parsing.pkg.AndroidPackage
|
import com.android.server.pm.parsing.pkg.AndroidPackage
|
||||||
import com.android.server.pm.pkg.PackageStateInternal
|
import com.android.server.pm.pkg.PackageStateInternal
|
||||||
import com.android.server.pm.pkg.PackageUserStateInternal
|
import com.android.server.pm.pkg.PackageUserStateInternal
|
||||||
import com.android.server.pm.test.verify.domain.DomainVerificationTestUtils.mockPackageStates
|
|
||||||
import com.android.server.pm.verify.domain.DomainVerificationService
|
import com.android.server.pm.verify.domain.DomainVerificationService
|
||||||
import com.android.server.testutils.mockThrowOnUnmocked
|
import com.android.server.testutils.mockThrowOnUnmocked
|
||||||
import com.android.server.testutils.whenever
|
import com.android.server.testutils.whenever
|
||||||
@@ -85,11 +84,15 @@ class DomainVerificationUserStateOverrideTest {
|
|||||||
// Need to provide an internal UID so some permission checks are ignored
|
// Need to provide an internal UID so some permission checks are ignored
|
||||||
whenever(callingUid) { Process.ROOT_UID }
|
whenever(callingUid) { Process.ROOT_UID }
|
||||||
whenever(callingUserId) { 0 }
|
whenever(callingUserId) { 0 }
|
||||||
mockPackageStates {
|
whenever(snapshot()) {
|
||||||
when (it) {
|
mockThrowOnUnmocked {
|
||||||
PKG_ONE -> pkg1
|
whenever(getPackageStateInternal(anyString())) {
|
||||||
PKG_TWO -> pkg2
|
when (getArgument<String>(0)) {
|
||||||
else -> null
|
PKG_ONE -> pkg1
|
||||||
|
PKG_TWO -> pkg2
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
|
|||||||
}
|
}
|
||||||
whenever(mocks.settings.packagesLocked).thenReturn(mSettingsMap)
|
whenever(mocks.settings.packagesLocked).thenReturn(mSettingsMap)
|
||||||
whenever(mocks.settings.getPackageLPr(anyString())) { mSettingsMap[getArgument<Any>(0)] }
|
whenever(mocks.settings.getPackageLPr(anyString())) { mSettingsMap[getArgument<Any>(0)] }
|
||||||
whenever(mocks.settings.readLPw(nullable())) {
|
whenever(mocks.settings.readLPw(any(), nullable())) {
|
||||||
mSettingsMap.putAll(mPreExistingSettings)
|
mSettingsMap.putAll(mPreExistingSettings)
|
||||||
!mPreExistingSettings.isEmpty()
|
!mPreExistingSettings.isEmpty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,17 +120,16 @@ class SharedLibrariesImplTest {
|
|||||||
whenever(mStorageManager.findPathForUuid(nullable())).thenReturn(mFile)
|
whenever(mStorageManager.findPathForUuid(nullable())).thenReturn(mFile)
|
||||||
doAnswer { it.arguments[0] }.`when`(mPms).resolveInternalPackageName(any(), any())
|
doAnswer { it.arguments[0] }.`when`(mPms).resolveInternalPackageName(any(), any())
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.getArgument<FunctionalUtils.ThrowingConsumer<Computer>>(0).acceptOrThrow(
|
mockThrowOnUnmocked<Computer> {
|
||||||
mockThrowOnUnmocked {
|
whenever(sharedLibraries) { mSharedLibrariesImpl.sharedLibraries }
|
||||||
whenever(sharedLibraries) { mSharedLibrariesImpl.sharedLibraries }
|
whenever(resolveInternalPackageName(anyString(), anyLong())) {
|
||||||
whenever(resolveInternalPackageName(anyString(), anyLong())) {
|
mPms.resolveInternalPackageName(getArgument(0), getArgument(1))
|
||||||
mPms.resolveInternalPackageName(getArgument(0), getArgument(1))
|
}
|
||||||
}
|
whenever(getPackageStateInternal(anyString())) {
|
||||||
whenever(getPackageStateInternal(anyString())) {
|
mPms.getPackageStateInternal(getArgument(0))
|
||||||
mPms.getPackageStateInternal(getArgument(0))
|
}
|
||||||
}
|
}
|
||||||
})
|
}.`when`(mPms).snapshotComputer()
|
||||||
}.`when`(mPms).executeWithConsistentComputer(any())
|
|
||||||
whenever(mDeletePackageHelper.deletePackageX(any(), any(), any(), any(), any()))
|
whenever(mDeletePackageHelper.deletePackageX(any(), any(), any(), any(), any()))
|
||||||
.thenReturn(PackageManager.DELETE_SUCCEEDED)
|
.thenReturn(PackageManager.DELETE_SUCCEEDED)
|
||||||
whenever(mRule.mocks().injector.compatibility).thenReturn(mPlatformCompat)
|
whenever(mRule.mocks().injector.compatibility).thenReturn(mPlatformCompat)
|
||||||
@@ -206,7 +205,8 @@ class SharedLibrariesImplTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun pruneUnusedStaticSharedLibraries() {
|
fun pruneUnusedStaticSharedLibraries() {
|
||||||
mSharedLibrariesImpl.pruneUnusedStaticSharedLibraries(Long.MAX_VALUE, 0)
|
mSharedLibrariesImpl.pruneUnusedStaticSharedLibraries(mPms.snapshotComputer(),
|
||||||
|
Long.MAX_VALUE, 0)
|
||||||
|
|
||||||
verify(mDeletePackageHelper)
|
verify(mDeletePackageHelper)
|
||||||
.deletePackageX(eq(STATIC_LIB_PACKAGE_NAME), any(), any(), any(), any())
|
.deletePackageX(eq(STATIC_LIB_PACKAGE_NAME), any(), any(), any(), any())
|
||||||
|
|||||||
@@ -123,8 +123,8 @@ class SuspendPackageHelperTest {
|
|||||||
@Test
|
@Test
|
||||||
fun setPackagesSuspended() {
|
fun setPackagesSuspended() {
|
||||||
val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
||||||
val failedNames = suspendPackageHelper.setPackagesSuspended(targetPackages,
|
val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
targetPackages, true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
|
|
||||||
@@ -144,14 +144,15 @@ class SuspendPackageHelperTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setPackagesSuspended_emptyPackageName() {
|
fun setPackagesSuspended_emptyPackageName() {
|
||||||
var failedNames = suspendPackageHelper.setPackagesSuspended(null /* packageNames */,
|
var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
null /* packageNames */, true /* suspended */, null /* appExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID,
|
||||||
|
deviceOwnerUid)
|
||||||
|
|
||||||
assertThat(failedNames).isNull()
|
assertThat(failedNames).isNull()
|
||||||
|
|
||||||
failedNames = suspendPackageHelper.setPackagesSuspended(arrayOfNulls(0),
|
failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
arrayOfNulls(0), true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
||||||
|
|
||||||
assertThat(failedNames).isEmpty()
|
assertThat(failedNames).isEmpty()
|
||||||
@@ -159,9 +160,10 @@ class SuspendPackageHelperTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setPackagesSuspended_callerIsNotAllowed() {
|
fun setPackagesSuspended_callerIsNotAllowed() {
|
||||||
val failedNames = suspendPackageHelper.setPackagesSuspended(arrayOf(TEST_PACKAGE_2),
|
val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
arrayOf(TEST_PACKAGE_2), true /* suspended */, null /* appExtras */,
|
||||||
null /* dialogInfo */, TEST_PACKAGE_1, TEST_USER_ID, Binder.getCallingUid())
|
null /* launcherExtras */, null /* dialogInfo */, TEST_PACKAGE_1, TEST_USER_ID,
|
||||||
|
Binder.getCallingUid())
|
||||||
|
|
||||||
assertThat(failedNames).asList().hasSize(1)
|
assertThat(failedNames).asList().hasSize(1)
|
||||||
assertThat(failedNames).asList().contains(TEST_PACKAGE_2)
|
assertThat(failedNames).asList().contains(TEST_PACKAGE_2)
|
||||||
@@ -169,9 +171,10 @@ class SuspendPackageHelperTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setPackagesSuspended_callerSuspendItself() {
|
fun setPackagesSuspended_callerSuspendItself() {
|
||||||
val failedNames = suspendPackageHelper.setPackagesSuspended(arrayOf(DEVICE_OWNER_PACKAGE),
|
val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
arrayOf(DEVICE_OWNER_PACKAGE), true /* suspended */, null /* appExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID,
|
||||||
|
deviceOwnerUid)
|
||||||
|
|
||||||
assertThat(failedNames).asList().hasSize(1)
|
assertThat(failedNames).asList().hasSize(1)
|
||||||
assertThat(failedNames).asList().contains(DEVICE_OWNER_PACKAGE)
|
assertThat(failedNames).asList().contains(DEVICE_OWNER_PACKAGE)
|
||||||
@@ -179,9 +182,10 @@ class SuspendPackageHelperTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setPackagesSuspended_nonexistentPackage() {
|
fun setPackagesSuspended_nonexistentPackage() {
|
||||||
val failedNames = suspendPackageHelper.setPackagesSuspended(arrayOf(NONEXISTENT_PACKAGE),
|
val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
arrayOf(NONEXISTENT_PACKAGE), true /* suspended */, null /* appExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID,
|
||||||
|
deviceOwnerUid)
|
||||||
|
|
||||||
assertThat(failedNames).asList().hasSize(1)
|
assertThat(failedNames).asList().hasSize(1)
|
||||||
assertThat(failedNames).asList().contains(NONEXISTENT_PACKAGE)
|
assertThat(failedNames).asList().contains(NONEXISTENT_PACKAGE)
|
||||||
@@ -191,8 +195,8 @@ class SuspendPackageHelperTest {
|
|||||||
fun setPackagesSuspended_knownPackages() {
|
fun setPackagesSuspended_knownPackages() {
|
||||||
val knownPackages = arrayOf(DEVICE_ADMIN_PACKAGE, DEFAULT_HOME_PACKAGE, DIALER_PACKAGE,
|
val knownPackages = arrayOf(DEVICE_ADMIN_PACKAGE, DEFAULT_HOME_PACKAGE, DIALER_PACKAGE,
|
||||||
INSTALLER_PACKAGE, UNINSTALLER_PACKAGE, VERIFIER_PACKAGE, PERMISSION_CONTROLLER_PACKAGE)
|
INSTALLER_PACKAGE, UNINSTALLER_PACKAGE, VERIFIER_PACKAGE, PERMISSION_CONTROLLER_PACKAGE)
|
||||||
val failedNames = suspendPackageHelper.setPackagesSuspended(knownPackages,
|
val failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
knownPackages, true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)!!
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)!!
|
||||||
|
|
||||||
assertThat(failedNames.size).isEqualTo(knownPackages.size)
|
assertThat(failedNames.size).isEqualTo(knownPackages.size)
|
||||||
@@ -204,13 +208,13 @@ class SuspendPackageHelperTest {
|
|||||||
@Test
|
@Test
|
||||||
fun setPackagesUnsuspended() {
|
fun setPackagesUnsuspended() {
|
||||||
val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
||||||
var failedNames = suspendPackageHelper.setPackagesSuspended(targetPackages,
|
var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
targetPackages, true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
assertThat(failedNames).isEmpty()
|
assertThat(failedNames).isEmpty()
|
||||||
failedNames = suspendPackageHelper.setPackagesSuspended(targetPackages,
|
failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
false /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
targetPackages, false /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
|
|
||||||
@@ -235,7 +239,7 @@ class SuspendPackageHelperTest {
|
|||||||
val suspendables = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
val suspendables = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
||||||
val unsuspendables = arrayOf(DEVICE_ADMIN_PACKAGE, DEFAULT_HOME_PACKAGE, DIALER_PACKAGE,
|
val unsuspendables = arrayOf(DEVICE_ADMIN_PACKAGE, DEFAULT_HOME_PACKAGE, DIALER_PACKAGE,
|
||||||
INSTALLER_PACKAGE, UNINSTALLER_PACKAGE, VERIFIER_PACKAGE, PERMISSION_CONTROLLER_PACKAGE)
|
INSTALLER_PACKAGE, UNINSTALLER_PACKAGE, VERIFIER_PACKAGE, PERMISSION_CONTROLLER_PACKAGE)
|
||||||
val results = suspendPackageHelper.getUnsuspendablePackagesForUser(
|
val results = suspendPackageHelper.getUnsuspendablePackagesForUser(pms.snapshotComputer(),
|
||||||
suspendables + unsuspendables, TEST_USER_ID, deviceOwnerUid)
|
suspendables + unsuspendables, TEST_USER_ID, deviceOwnerUid)
|
||||||
|
|
||||||
assertThat(results.size).isEqualTo(unsuspendables.size)
|
assertThat(results.size).isEqualTo(unsuspendables.size)
|
||||||
@@ -247,7 +251,7 @@ class SuspendPackageHelperTest {
|
|||||||
@Test
|
@Test
|
||||||
fun getUnsuspendablePackagesForUser_callerIsNotAllowed() {
|
fun getUnsuspendablePackagesForUser_callerIsNotAllowed() {
|
||||||
val suspendables = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
val suspendables = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
||||||
val results = suspendPackageHelper.getUnsuspendablePackagesForUser(
|
val results = suspendPackageHelper.getUnsuspendablePackagesForUser(pms.snapshotComputer(),
|
||||||
suspendables, TEST_USER_ID, Binder.getCallingUid())
|
suspendables, TEST_USER_ID, Binder.getCallingUid())
|
||||||
|
|
||||||
assertThat(results.size).isEqualTo(suspendables.size)
|
assertThat(results.size).isEqualTo(suspendables.size)
|
||||||
@@ -260,8 +264,8 @@ class SuspendPackageHelperTest {
|
|||||||
fun getSuspendedPackageAppExtras() {
|
fun getSuspendedPackageAppExtras() {
|
||||||
val appExtras = PersistableBundle()
|
val appExtras = PersistableBundle()
|
||||||
appExtras.putString(TEST_PACKAGE_1, TEST_PACKAGE_1)
|
appExtras.putString(TEST_PACKAGE_1, TEST_PACKAGE_1)
|
||||||
var failedNames = suspendPackageHelper.setPackagesSuspended(arrayOf(TEST_PACKAGE_1),
|
var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, appExtras, null /* launcherExtras */,
|
arrayOf(TEST_PACKAGE_1), true /* suspended */, appExtras, null /* launcherExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
assertThat(failedNames).isEmpty()
|
assertThat(failedNames).isEmpty()
|
||||||
@@ -277,8 +281,8 @@ class SuspendPackageHelperTest {
|
|||||||
val appExtras = PersistableBundle()
|
val appExtras = PersistableBundle()
|
||||||
appExtras.putString(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
appExtras.putString(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
||||||
val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
val targetPackages = arrayOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
|
||||||
var failedNames = suspendPackageHelper.setPackagesSuspended(targetPackages,
|
var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, appExtras, null /* launcherExtras */,
|
targetPackages, true /* suspended */, appExtras, null /* launcherExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
assertThat(failedNames).isEmpty()
|
assertThat(failedNames).isEmpty()
|
||||||
@@ -291,8 +295,9 @@ class SuspendPackageHelperTest {
|
|||||||
assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(
|
assertThat(suspendPackageHelper.getSuspendedPackageAppExtras(
|
||||||
TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isNotNull()
|
TEST_PACKAGE_2, TEST_USER_ID, deviceOwnerUid)).isNotNull()
|
||||||
|
|
||||||
suspendPackageHelper.removeSuspensionsBySuspendingPackage(targetPackages,
|
suspendPackageHelper.removeSuspensionsBySuspendingPackage(pms.snapshotComputer(),
|
||||||
{ suspendingPackage -> suspendingPackage == DEVICE_OWNER_PACKAGE }, TEST_USER_ID)
|
targetPackages, { suspendingPackage -> suspendingPackage == DEVICE_OWNER_PACKAGE },
|
||||||
|
TEST_USER_ID)
|
||||||
|
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
verify(pms, times(2)).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
|
verify(pms, times(2)).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
|
||||||
@@ -320,8 +325,8 @@ class SuspendPackageHelperTest {
|
|||||||
fun getSuspendedPackageLauncherExtras() {
|
fun getSuspendedPackageLauncherExtras() {
|
||||||
val launcherExtras = PersistableBundle()
|
val launcherExtras = PersistableBundle()
|
||||||
launcherExtras.putString(TEST_PACKAGE_2, TEST_PACKAGE_2)
|
launcherExtras.putString(TEST_PACKAGE_2, TEST_PACKAGE_2)
|
||||||
var failedNames = suspendPackageHelper.setPackagesSuspended(arrayOf(TEST_PACKAGE_2),
|
var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, launcherExtras,
|
arrayOf(TEST_PACKAGE_2), true /* suspended */, null /* appExtras */, launcherExtras,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
assertThat(failedNames).isEmpty()
|
assertThat(failedNames).isEmpty()
|
||||||
@@ -334,9 +339,10 @@ class SuspendPackageHelperTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isPackageSuspended() {
|
fun isPackageSuspended() {
|
||||||
var failedNames = suspendPackageHelper.setPackagesSuspended(arrayOf(TEST_PACKAGE_1),
|
var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
arrayOf(TEST_PACKAGE_1), true /* suspended */, null /* appExtras */,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* launcherExtras */, null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID,
|
||||||
|
deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
assertThat(failedNames).isEmpty()
|
assertThat(failedNames).isEmpty()
|
||||||
|
|
||||||
@@ -348,8 +354,8 @@ class SuspendPackageHelperTest {
|
|||||||
fun getSuspendingPackage() {
|
fun getSuspendingPackage() {
|
||||||
val launcherExtras = PersistableBundle()
|
val launcherExtras = PersistableBundle()
|
||||||
launcherExtras.putString(TEST_PACKAGE_2, TEST_PACKAGE_2)
|
launcherExtras.putString(TEST_PACKAGE_2, TEST_PACKAGE_2)
|
||||||
var failedNames = suspendPackageHelper.setPackagesSuspended(arrayOf(TEST_PACKAGE_2),
|
var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, launcherExtras,
|
arrayOf(TEST_PACKAGE_2), true /* suspended */, null /* appExtras */, launcherExtras,
|
||||||
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* dialogInfo */, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
assertThat(failedNames).isEmpty()
|
assertThat(failedNames).isEmpty()
|
||||||
@@ -362,9 +368,10 @@ class SuspendPackageHelperTest {
|
|||||||
fun getSuspendedDialogInfo() {
|
fun getSuspendedDialogInfo() {
|
||||||
val dialogInfo = SuspendDialogInfo.Builder()
|
val dialogInfo = SuspendDialogInfo.Builder()
|
||||||
.setTitle(TEST_PACKAGE_1).build()
|
.setTitle(TEST_PACKAGE_1).build()
|
||||||
var failedNames = suspendPackageHelper.setPackagesSuspended(arrayOf(TEST_PACKAGE_1),
|
var failedNames = suspendPackageHelper.setPackagesSuspended(pms.snapshotComputer(),
|
||||||
true /* suspended */, null /* appExtras */, null /* launcherExtras */,
|
arrayOf(TEST_PACKAGE_1), true /* suspended */, null /* appExtras */,
|
||||||
dialogInfo, DEVICE_OWNER_PACKAGE, TEST_USER_ID, deviceOwnerUid)
|
null /* launcherExtras */, dialogInfo, DEVICE_OWNER_PACKAGE, TEST_USER_ID,
|
||||||
|
deviceOwnerUid)
|
||||||
testHandler.flush()
|
testHandler.flush()
|
||||||
assertThat(failedNames).isEmpty()
|
assertThat(failedNames).isEmpty()
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import static org.junit.Assert.assertNotSame;
|
|||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -109,6 +110,8 @@ public class PackageManagerSettingsTests {
|
|||||||
LegacyPermissionDataProvider mPermissionDataProvider;
|
LegacyPermissionDataProvider mPermissionDataProvider;
|
||||||
@Mock
|
@Mock
|
||||||
DomainVerificationManagerInternal mDomainVerificationManager;
|
DomainVerificationManagerInternal mDomainVerificationManager;
|
||||||
|
@Mock
|
||||||
|
Computer computer;
|
||||||
|
|
||||||
final ArrayMap<String, Long> mOrigFirstInstallTimes = new ArrayMap<>();
|
final ArrayMap<String, Long> mOrigFirstInstallTimes = new ArrayMap<>();
|
||||||
|
|
||||||
@@ -132,7 +135,7 @@ public class PackageManagerSettingsTests {
|
|||||||
/* write out files and read */
|
/* write out files and read */
|
||||||
writeOldFiles();
|
writeOldFiles();
|
||||||
Settings settings = makeSettings();
|
Settings settings = makeSettings();
|
||||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
|
||||||
verifyKeySetMetaData(settings);
|
verifyKeySetMetaData(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,11 +146,11 @@ public class PackageManagerSettingsTests {
|
|||||||
// write out files and read
|
// write out files and read
|
||||||
writeOldFiles();
|
writeOldFiles();
|
||||||
Settings settings = makeSettings();
|
Settings settings = makeSettings();
|
||||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
|
||||||
|
|
||||||
// write out, read back in and verify the same
|
// write out, read back in and verify the same
|
||||||
settings.writeLPr();
|
settings.writeLPr(computer);
|
||||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
|
||||||
verifyKeySetMetaData(settings);
|
verifyKeySetMetaData(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +159,7 @@ public class PackageManagerSettingsTests {
|
|||||||
// Write delegateshellthe package files and make sure they're parsed properly the first time
|
// Write delegateshellthe package files and make sure they're parsed properly the first time
|
||||||
writeOldFiles();
|
writeOldFiles();
|
||||||
Settings settings = makeSettings();
|
Settings settings = makeSettings();
|
||||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
|
||||||
assertThat(settings.getPackageLPr(PACKAGE_NAME_3), is(notNullValue()));
|
assertThat(settings.getPackageLPr(PACKAGE_NAME_3), is(notNullValue()));
|
||||||
assertThat(settings.getPackageLPr(PACKAGE_NAME_1), is(notNullValue()));
|
assertThat(settings.getPackageLPr(PACKAGE_NAME_1), is(notNullValue()));
|
||||||
|
|
||||||
@@ -175,12 +178,12 @@ public class PackageManagerSettingsTests {
|
|||||||
// Write the package files and make sure they're parsed properly the first time
|
// Write the package files and make sure they're parsed properly the first time
|
||||||
writeOldFiles();
|
writeOldFiles();
|
||||||
Settings settings = makeSettings();
|
Settings settings = makeSettings();
|
||||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
|
||||||
settings.writeLPr();
|
settings.writeLPr(computer);
|
||||||
|
|
||||||
// Create Settings again to make it read from the new files
|
// Create Settings again to make it read from the new files
|
||||||
settings = makeSettings();
|
settings = makeSettings();
|
||||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
|
||||||
|
|
||||||
PackageSetting ps = settings.getPackageLPr(PACKAGE_NAME_2);
|
PackageSetting ps = settings.getPackageLPr(PACKAGE_NAME_2);
|
||||||
assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DISABLED_USER));
|
assertThat(ps.getEnabled(0), is(COMPONENT_ENABLED_STATE_DISABLED_USER));
|
||||||
@@ -469,12 +472,12 @@ public class PackageManagerSettingsTests {
|
|||||||
ps2.setUsesStaticLibrariesVersions(new long[] { 34 });
|
ps2.setUsesStaticLibrariesVersions(new long[] { 34 });
|
||||||
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
|
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
|
||||||
|
|
||||||
settingsUnderTest.writeLPr();
|
settingsUnderTest.writeLPr(computer);
|
||||||
|
|
||||||
settingsUnderTest.mPackages.clear();
|
settingsUnderTest.mPackages.clear();
|
||||||
settingsUnderTest.mDisabledSysPackages.clear();
|
settingsUnderTest.mDisabledSysPackages.clear();
|
||||||
|
|
||||||
assertThat(settingsUnderTest.readLPw(createFakeUsers()), is(true));
|
assertThat(settingsUnderTest.readLPw(computer, createFakeUsers()), is(true));
|
||||||
|
|
||||||
PackageSetting readPs1 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_1);
|
PackageSetting readPs1 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_1);
|
||||||
PackageSetting readPs2 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_2);
|
PackageSetting readPs2 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_2);
|
||||||
@@ -534,12 +537,12 @@ public class PackageManagerSettingsTests {
|
|||||||
ps2.setUsesSdkLibrariesVersionsMajor(new long[] { 34 });
|
ps2.setUsesSdkLibrariesVersionsMajor(new long[] { 34 });
|
||||||
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
|
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
|
||||||
|
|
||||||
settingsUnderTest.writeLPr();
|
settingsUnderTest.writeLPr(computer);
|
||||||
|
|
||||||
settingsUnderTest.mPackages.clear();
|
settingsUnderTest.mPackages.clear();
|
||||||
settingsUnderTest.mDisabledSysPackages.clear();
|
settingsUnderTest.mDisabledSysPackages.clear();
|
||||||
|
|
||||||
assertThat(settingsUnderTest.readLPw(createFakeUsers()), is(true));
|
assertThat(settingsUnderTest.readLPw(computer, createFakeUsers()), is(true));
|
||||||
|
|
||||||
PackageSetting readPs1 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_1);
|
PackageSetting readPs1 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_1);
|
||||||
PackageSetting readPs2 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_2);
|
PackageSetting readPs2 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_2);
|
||||||
@@ -587,7 +590,7 @@ public class PackageManagerSettingsTests {
|
|||||||
Settings settings = makeSettings();
|
Settings settings = makeSettings();
|
||||||
final WatchableTester watcher = new WatchableTester(settings, "testEnableDisable");
|
final WatchableTester watcher = new WatchableTester(settings, "testEnableDisable");
|
||||||
watcher.register();
|
watcher.register();
|
||||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
|
||||||
watcher.verifyChangeReported("readLPw");
|
watcher.verifyChangeReported("readLPw");
|
||||||
|
|
||||||
// Enable/Disable a package
|
// Enable/Disable a package
|
||||||
|
|||||||
Reference in New Issue
Block a user