Loading services/core/java/com/android/server/pm/BroadcastHelper.java +0 −11 Original line number Diff line number Diff line Loading @@ -320,17 +320,6 @@ public final class BroadcastHelper { broadcastAllowlist, null); } public void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId, int distractionFlags) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null, null, null); } public void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds, int[] instantUserIds) { sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, Loading services/core/java/com/android/server/pm/DistractingPackageHelper.java 0 → 100644 +198 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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; import static android.content.pm.PackageManager.RESTRICTION_NONE; import android.annotation.NonNull; import android.content.Intent; import android.content.pm.PackageManager.DistractionRestriction; import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.util.ArraySet; import android.util.IntArray; import android.util.Slog; import com.android.internal.util.ArrayUtils; import com.android.server.pm.pkg.PackageStateInternal; import java.util.ArrayList; import java.util.List; /** * Mark, unmark, or remove any {@link DistractionRestriction restrictions} set on given packages. */ public final class DistractingPackageHelper { // TODO(b/198166813): remove PMS dependency private final PackageManagerService mPm; private final PackageManagerServiceInjector mInjector; private final BroadcastHelper mBroadcastHelper; private final SuspendPackageHelper mSuspendPackageHelper; /** * Constructor for {@link PackageManagerService}. */ DistractingPackageHelper(PackageManagerService pm, PackageManagerServiceInjector injector, BroadcastHelper broadcastHelper, SuspendPackageHelper suspendPackageHelper) { mPm = pm; mInjector = injector; mBroadcastHelper = broadcastHelper; mSuspendPackageHelper = suspendPackageHelper; } /** * Mark or unmark the given packages as distracting to the given user. * * @param packageNames Packages to mark as distracting. * @param restrictionFlags Any combination of restrictions to impose on the given packages. * {@link DistractionRestriction#RESTRICTION_NONE} can be used to * clear any existing restrictions. * @param userId the user for which changes are taking place. * @param callingUid The caller's uid. * * @return A list of packages that could not have the {@code restrictionFlags} set. The system * may prevent restricting critical packages to preserve normal device function. */ String[] setDistractingPackageRestrictionsAsUser(@NonNull Computer snapshot, String[] packageNames, int restrictionFlags, int userId, int callingUid) { if (ArrayUtils.isEmpty(packageNames)) { return packageNames; } if (restrictionFlags != RESTRICTION_NONE && !mSuspendPackageHelper.isSuspendAllowedForUser(snapshot, userId, callingUid)) { Slog.w(PackageManagerService.TAG, "Cannot restrict packages due to restrictions on user " + userId); return packageNames; } final List<String> changedPackagesList = new ArrayList<>(packageNames.length); final IntArray changedUids = new IntArray(packageNames.length); final List<String> unactionedPackages = new ArrayList<>(packageNames.length); final ArraySet<String> changesToCommit = new ArraySet<>(); final boolean[] canRestrict = (restrictionFlags != RESTRICTION_NONE) ? mSuspendPackageHelper.canSuspendPackageForUser(snapshot, packageNames, userId, callingUid) : null; for (int i = 0; i < packageNames.length; i++) { final String packageName = packageNames[i]; final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName); if (packageState == null || snapshot.shouldFilterApplication(packageState, callingUid, userId)) { Slog.w(PackageManagerService.TAG, "Could not find package setting for package: " + packageName + ". Skipping..."); unactionedPackages.add(packageName); 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); } } mPm.commitPackageStateMutation(null /* initialState */, mutator -> { final int size = changesToCommit.size(); for (int index = 0; index < size; index++) { mutator.forPackage(changesToCommit.valueAt(index)) .userState(userId) .setDistractionFlags(restrictionFlags); } }); if (!changedPackagesList.isEmpty()) { final String[] changedPackages = changedPackagesList.toArray( new String[changedPackagesList.size()]); sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId, restrictionFlags); mPm.scheduleWritePackageRestrictions(userId); } return unactionedPackages.toArray(new String[0]); } /** * Removes any {@link DistractionRestriction restrictions} set on given packages. * * <p> Caller must flush package restrictions if it cares about immediate data consistency. * * @param packagesToChange The packages on which restrictions are to be removed. * @param userId the user for which changes are taking place. */ void removeDistractingPackageRestrictions(@NonNull Computer snapshot, String[] packagesToChange, int userId) { if (ArrayUtils.isEmpty(packagesToChange)) { return; } final List<String> changedPackages = new ArrayList<>(packagesToChange.length); final IntArray changedUids = new IntArray(packagesToChange.length); for (int i = 0; i < packagesToChange.length; i++) { final String packageName = packagesToChange[i]; final PackageStateInternal ps = snapshot.getPackageStateInternal(packageName); if (ps != null && ps.getUserStateOrDefault(userId).getDistractionFlags() != RESTRICTION_NONE) { changedPackages.add(ps.getPackageName()); changedUids.add(UserHandle.getUid(userId, ps.getAppId())); } } mPm.commitPackageStateMutation(null /* initialState */, mutator -> { for (int index = 0; index < changedPackages.size(); index++) { mutator.forPackage(changedPackages.get(index)) .userState(userId) .setDistractionFlags(RESTRICTION_NONE); } }); if (!changedPackages.isEmpty()) { final String[] packageArray = changedPackages.toArray( new String[changedPackages.size()]); sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, RESTRICTION_NONE); mPm.scheduleWritePackageRestrictions(userId); } } /** * Send broadcast intents for packages distracting changes. * * @param pkgList The names of packages which have suspension changes. * @param uidList The uids of packages which have suspension changes. * @param userId The user where packages reside. */ void sendDistractingPackagesChanged(@NonNull String[] pkgList, int[] uidList, int userId, int distractionFlags) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); final Handler handler = mInjector.getHandler(); handler.post(() -> mBroadcastHelper.sendPackageBroadcast( Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */, null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */, null /* allowList */, null /* bOptions */)); } } services/core/java/com/android/server/pm/PackageManagerInternalBase.java +3 −2 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { @NonNull protected abstract PackageObserverHelper getPackageObserverHelper(); @NonNull protected abstract ResolveIntentHelper getResolveIntentHelper(); @NonNull protected abstract SuspendPackageHelper getSuspendPackageHelper(); @NonNull protected abstract DistractingPackageHelper getDistractingPackageHelper(); @NonNull protected abstract ProtectedPackages getProtectedPackages(); @NonNull protected abstract UserNeedsBadgingCache getUserNeedsBadging(); @NonNull protected abstract InstantAppRegistry getInstantAppRegistry(); Loading Loading @@ -248,8 +249,8 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { @Override @Deprecated public final void removeDistractingPackageRestrictions(String packageName, int userId) { mService.removeDistractingPackageRestrictions(snapshot(), new String[]{packageName}, userId); getDistractingPackageHelper().removeDistractingPackageRestrictions(snapshot(), new String[]{packageName}, userId); } @Override Loading services/core/java/com/android/server/pm/PackageManagerService.java +25 −100 Original line number Diff line number Diff line Loading @@ -157,7 +157,6 @@ import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.ExceptionUtils; import android.util.IntArray; import android.util.Log; import android.util.Pair; import android.util.Slog; Loading Loading @@ -937,6 +936,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService private final ResolveIntentHelper mResolveIntentHelper; private final DexOptHelper mDexOptHelper; private final SuspendPackageHelper mSuspendPackageHelper; private final DistractingPackageHelper mDistractingPackageHelper; private final IntentResolverInterceptor mIntentResolverInterceptor; /** Loading Loading @@ -1680,6 +1680,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService mResolveIntentHelper = testParams.resolveIntentHelper; mDexOptHelper = testParams.dexOptHelper; mSuspendPackageHelper = testParams.suspendPackageHelper; mDistractingPackageHelper = testParams.distractingPackageHelper; mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper); Loading Loading @@ -1836,6 +1837,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService mDexOptHelper = new DexOptHelper(this); mSuspendPackageHelper = new SuspendPackageHelper(this, mInjector, mBroadcastHelper, mProtectedPackages); mDistractingPackageHelper = new DistractingPackageHelper(this, mInjector, mBroadcastHelper, mSuspendPackageHelper); synchronized (mLock) { // Create the computer as soon as the state objects have been installed. The Loading Loading @@ -3059,43 +3062,19 @@ public class PackageManagerService implements PackageSender, TestUtilityService void removeAllDistractingPackageRestrictions(@NonNull Computer snapshot, int userId) { final String[] allPackages = snapshot.getAllAvailablePackageNames(); removeDistractingPackageRestrictions(snapshot, allPackages, userId); mDistractingPackageHelper.removeDistractingPackageRestrictions(snapshot, allPackages, userId); } /** * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions} * set on given packages. * * <p> Caller must flush package restrictions if it cares about immediate data consistency. * * @param packagesToChange The packages on which restrictions are to be removed. * @param userId the user for which changes are taking place. */ void removeDistractingPackageRestrictions(@NonNull Computer snapshot, String[] packagesToChange, int userId) { final List<String> changedPackages = new ArrayList<>(); final IntArray changedUids = new IntArray(); for (String packageName : packagesToChange) { final PackageStateInternal ps = snapshot.getPackageStateInternal(packageName); if (ps != null && ps.getUserStateOrDefault(userId).getDistractionFlags() != 0) { changedPackages.add(ps.getPackageName()); changedUids.add(UserHandle.getUid(userId, ps.getAppId())); } } commitPackageStateMutation(null, mutator -> { for (int index = 0; index < changedPackages.size(); index++) { mutator.forPackage(changedPackages.get(index)) .userState(userId) .setDistractionFlags(0); } }); private void enforceCanSetDistractingPackageRestrictionsAsUser(@NonNull Computer snapshot, int callingUid, int userId, String callingMethod) { mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, callingMethod); if (!changedPackages.isEmpty()) { final String[] packageArray = changedPackages.toArray( new String[changedPackages.size()]); mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged( packageArray, changedUids.toArray(), userId, 0)); scheduleWritePackageRestrictions(userId); if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID && UserHandle.getUserId(callingUid) != userId) { throw new SecurityException("Calling uid " + callingUid + " cannot call for user " + userId); } } Loading Loading @@ -5595,73 +5574,13 @@ public class PackageManagerService implements PackageSender, TestUtilityService @Override public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames, int restrictionFlags, int userId) { mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, "setDistractingPackageRestrictionsAsUser"); final int callingUid = Binder.getCallingUid(); if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID && UserHandle.getUserId(callingUid) != userId) { throw new SecurityException("Calling uid " + callingUid + " cannot call for user " + userId); } Objects.requireNonNull(packageNames, "packageNames cannot be null"); final Computer snapshot = snapshotComputer(); if (restrictionFlags != 0 && !mSuspendPackageHelper.isSuspendAllowedForUser(snapshot, userId, callingUid)) { Slog.w(PackageManagerService.TAG, "Cannot restrict packages due to restrictions on user " + userId); return packageNames; } final List<String> changedPackagesList = new ArrayList<>(packageNames.length); final IntArray changedUids = new IntArray(packageNames.length); final List<String> unactionedPackages = new ArrayList<>(packageNames.length); ArraySet<String> changesToCommit = new ArraySet<>(); final boolean[] canRestrict = (restrictionFlags != 0) ? mSuspendPackageHelper.canSuspendPackageForUser(snapshot, packageNames, userId, callingUid) : null; for (int i = 0; i < packageNames.length; i++) { final String packageName = packageNames[i]; final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName); if (packageState == null || snapshot.shouldFilterApplication(packageState, callingUid, userId)) { Slog.w(PackageManagerService.TAG, "Could not find package setting for package: " + packageName + ". Skipping..."); unactionedPackages.add(packageName); 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); } } commitPackageStateMutation(null, mutator -> { final int size = changesToCommit.size(); for (int index = 0; index < size; index++) { mutator.forPackage(changesToCommit.valueAt(index)) .userState(userId) .setDistractionFlags(restrictionFlags); } }); if (!changedPackagesList.isEmpty()) { final String[] changedPackages = changedPackagesList.toArray( new String[changedPackagesList.size()]); mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged( changedPackages, changedUids.toArray(), userId, restrictionFlags)); scheduleWritePackageRestrictions(userId); } return unactionedPackages.toArray(new String[0]); enforceCanSetDistractingPackageRestrictionsAsUser(snapshot, callingUid, userId, "setDistractingPackageRestrictionsAsUser"); Objects.requireNonNull(packageNames, "packageNames cannot be null"); return mDistractingPackageHelper.setDistractingPackageRestrictionsAsUser(snapshot, packageNames, restrictionFlags, userId, callingUid); } @Override Loading Loading @@ -6093,6 +6012,12 @@ public class PackageManagerService implements PackageSender, TestUtilityService return mSuspendPackageHelper; } @NonNull @Override protected DistractingPackageHelper getDistractingPackageHelper() { return mDistractingPackageHelper; } @NonNull @Override protected ProtectedPackages getProtectedPackages() { Loading services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java +1 −0 Original line number Diff line number Diff line Loading @@ -115,4 +115,5 @@ public final class PackageManagerServiceTestParams { public ResolveIntentHelper resolveIntentHelper; public DexOptHelper dexOptHelper; public SuspendPackageHelper suspendPackageHelper; public DistractingPackageHelper distractingPackageHelper; } Loading
services/core/java/com/android/server/pm/BroadcastHelper.java +0 −11 Original line number Diff line number Diff line Loading @@ -320,17 +320,6 @@ public final class BroadcastHelper { broadcastAllowlist, null); } public void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId, int distractionFlags) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null, null, null); } public void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds, int[] instantUserIds) { sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, Loading
services/core/java/com/android/server/pm/DistractingPackageHelper.java 0 → 100644 +198 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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; import static android.content.pm.PackageManager.RESTRICTION_NONE; import android.annotation.NonNull; import android.content.Intent; import android.content.pm.PackageManager.DistractionRestriction; import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.util.ArraySet; import android.util.IntArray; import android.util.Slog; import com.android.internal.util.ArrayUtils; import com.android.server.pm.pkg.PackageStateInternal; import java.util.ArrayList; import java.util.List; /** * Mark, unmark, or remove any {@link DistractionRestriction restrictions} set on given packages. */ public final class DistractingPackageHelper { // TODO(b/198166813): remove PMS dependency private final PackageManagerService mPm; private final PackageManagerServiceInjector mInjector; private final BroadcastHelper mBroadcastHelper; private final SuspendPackageHelper mSuspendPackageHelper; /** * Constructor for {@link PackageManagerService}. */ DistractingPackageHelper(PackageManagerService pm, PackageManagerServiceInjector injector, BroadcastHelper broadcastHelper, SuspendPackageHelper suspendPackageHelper) { mPm = pm; mInjector = injector; mBroadcastHelper = broadcastHelper; mSuspendPackageHelper = suspendPackageHelper; } /** * Mark or unmark the given packages as distracting to the given user. * * @param packageNames Packages to mark as distracting. * @param restrictionFlags Any combination of restrictions to impose on the given packages. * {@link DistractionRestriction#RESTRICTION_NONE} can be used to * clear any existing restrictions. * @param userId the user for which changes are taking place. * @param callingUid The caller's uid. * * @return A list of packages that could not have the {@code restrictionFlags} set. The system * may prevent restricting critical packages to preserve normal device function. */ String[] setDistractingPackageRestrictionsAsUser(@NonNull Computer snapshot, String[] packageNames, int restrictionFlags, int userId, int callingUid) { if (ArrayUtils.isEmpty(packageNames)) { return packageNames; } if (restrictionFlags != RESTRICTION_NONE && !mSuspendPackageHelper.isSuspendAllowedForUser(snapshot, userId, callingUid)) { Slog.w(PackageManagerService.TAG, "Cannot restrict packages due to restrictions on user " + userId); return packageNames; } final List<String> changedPackagesList = new ArrayList<>(packageNames.length); final IntArray changedUids = new IntArray(packageNames.length); final List<String> unactionedPackages = new ArrayList<>(packageNames.length); final ArraySet<String> changesToCommit = new ArraySet<>(); final boolean[] canRestrict = (restrictionFlags != RESTRICTION_NONE) ? mSuspendPackageHelper.canSuspendPackageForUser(snapshot, packageNames, userId, callingUid) : null; for (int i = 0; i < packageNames.length; i++) { final String packageName = packageNames[i]; final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName); if (packageState == null || snapshot.shouldFilterApplication(packageState, callingUid, userId)) { Slog.w(PackageManagerService.TAG, "Could not find package setting for package: " + packageName + ". Skipping..."); unactionedPackages.add(packageName); 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); } } mPm.commitPackageStateMutation(null /* initialState */, mutator -> { final int size = changesToCommit.size(); for (int index = 0; index < size; index++) { mutator.forPackage(changesToCommit.valueAt(index)) .userState(userId) .setDistractionFlags(restrictionFlags); } }); if (!changedPackagesList.isEmpty()) { final String[] changedPackages = changedPackagesList.toArray( new String[changedPackagesList.size()]); sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId, restrictionFlags); mPm.scheduleWritePackageRestrictions(userId); } return unactionedPackages.toArray(new String[0]); } /** * Removes any {@link DistractionRestriction restrictions} set on given packages. * * <p> Caller must flush package restrictions if it cares about immediate data consistency. * * @param packagesToChange The packages on which restrictions are to be removed. * @param userId the user for which changes are taking place. */ void removeDistractingPackageRestrictions(@NonNull Computer snapshot, String[] packagesToChange, int userId) { if (ArrayUtils.isEmpty(packagesToChange)) { return; } final List<String> changedPackages = new ArrayList<>(packagesToChange.length); final IntArray changedUids = new IntArray(packagesToChange.length); for (int i = 0; i < packagesToChange.length; i++) { final String packageName = packagesToChange[i]; final PackageStateInternal ps = snapshot.getPackageStateInternal(packageName); if (ps != null && ps.getUserStateOrDefault(userId).getDistractionFlags() != RESTRICTION_NONE) { changedPackages.add(ps.getPackageName()); changedUids.add(UserHandle.getUid(userId, ps.getAppId())); } } mPm.commitPackageStateMutation(null /* initialState */, mutator -> { for (int index = 0; index < changedPackages.size(); index++) { mutator.forPackage(changedPackages.get(index)) .userState(userId) .setDistractionFlags(RESTRICTION_NONE); } }); if (!changedPackages.isEmpty()) { final String[] packageArray = changedPackages.toArray( new String[changedPackages.size()]); sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, RESTRICTION_NONE); mPm.scheduleWritePackageRestrictions(userId); } } /** * Send broadcast intents for packages distracting changes. * * @param pkgList The names of packages which have suspension changes. * @param uidList The uids of packages which have suspension changes. * @param userId The user where packages reside. */ void sendDistractingPackagesChanged(@NonNull String[] pkgList, int[] uidList, int userId, int distractionFlags) { final Bundle extras = new Bundle(3); extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList); extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags); final Handler handler = mInjector.getHandler(); handler.post(() -> mBroadcastHelper.sendPackageBroadcast( Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */, null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */, null /* allowList */, null /* bOptions */)); } }
services/core/java/com/android/server/pm/PackageManagerInternalBase.java +3 −2 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { @NonNull protected abstract PackageObserverHelper getPackageObserverHelper(); @NonNull protected abstract ResolveIntentHelper getResolveIntentHelper(); @NonNull protected abstract SuspendPackageHelper getSuspendPackageHelper(); @NonNull protected abstract DistractingPackageHelper getDistractingPackageHelper(); @NonNull protected abstract ProtectedPackages getProtectedPackages(); @NonNull protected abstract UserNeedsBadgingCache getUserNeedsBadging(); @NonNull protected abstract InstantAppRegistry getInstantAppRegistry(); Loading Loading @@ -248,8 +249,8 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { @Override @Deprecated public final void removeDistractingPackageRestrictions(String packageName, int userId) { mService.removeDistractingPackageRestrictions(snapshot(), new String[]{packageName}, userId); getDistractingPackageHelper().removeDistractingPackageRestrictions(snapshot(), new String[]{packageName}, userId); } @Override Loading
services/core/java/com/android/server/pm/PackageManagerService.java +25 −100 Original line number Diff line number Diff line Loading @@ -157,7 +157,6 @@ import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.ExceptionUtils; import android.util.IntArray; import android.util.Log; import android.util.Pair; import android.util.Slog; Loading Loading @@ -937,6 +936,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService private final ResolveIntentHelper mResolveIntentHelper; private final DexOptHelper mDexOptHelper; private final SuspendPackageHelper mSuspendPackageHelper; private final DistractingPackageHelper mDistractingPackageHelper; private final IntentResolverInterceptor mIntentResolverInterceptor; /** Loading Loading @@ -1680,6 +1680,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService mResolveIntentHelper = testParams.resolveIntentHelper; mDexOptHelper = testParams.dexOptHelper; mSuspendPackageHelper = testParams.suspendPackageHelper; mDistractingPackageHelper = testParams.distractingPackageHelper; mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper); Loading Loading @@ -1836,6 +1837,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService mDexOptHelper = new DexOptHelper(this); mSuspendPackageHelper = new SuspendPackageHelper(this, mInjector, mBroadcastHelper, mProtectedPackages); mDistractingPackageHelper = new DistractingPackageHelper(this, mInjector, mBroadcastHelper, mSuspendPackageHelper); synchronized (mLock) { // Create the computer as soon as the state objects have been installed. The Loading Loading @@ -3059,43 +3062,19 @@ public class PackageManagerService implements PackageSender, TestUtilityService void removeAllDistractingPackageRestrictions(@NonNull Computer snapshot, int userId) { final String[] allPackages = snapshot.getAllAvailablePackageNames(); removeDistractingPackageRestrictions(snapshot, allPackages, userId); mDistractingPackageHelper.removeDistractingPackageRestrictions(snapshot, allPackages, userId); } /** * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions} * set on given packages. * * <p> Caller must flush package restrictions if it cares about immediate data consistency. * * @param packagesToChange The packages on which restrictions are to be removed. * @param userId the user for which changes are taking place. */ void removeDistractingPackageRestrictions(@NonNull Computer snapshot, String[] packagesToChange, int userId) { final List<String> changedPackages = new ArrayList<>(); final IntArray changedUids = new IntArray(); for (String packageName : packagesToChange) { final PackageStateInternal ps = snapshot.getPackageStateInternal(packageName); if (ps != null && ps.getUserStateOrDefault(userId).getDistractionFlags() != 0) { changedPackages.add(ps.getPackageName()); changedUids.add(UserHandle.getUid(userId, ps.getAppId())); } } commitPackageStateMutation(null, mutator -> { for (int index = 0; index < changedPackages.size(); index++) { mutator.forPackage(changedPackages.get(index)) .userState(userId) .setDistractionFlags(0); } }); private void enforceCanSetDistractingPackageRestrictionsAsUser(@NonNull Computer snapshot, int callingUid, int userId, String callingMethod) { mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, callingMethod); if (!changedPackages.isEmpty()) { final String[] packageArray = changedPackages.toArray( new String[changedPackages.size()]); mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged( packageArray, changedUids.toArray(), userId, 0)); scheduleWritePackageRestrictions(userId); if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID && UserHandle.getUserId(callingUid) != userId) { throw new SecurityException("Calling uid " + callingUid + " cannot call for user " + userId); } } Loading Loading @@ -5595,73 +5574,13 @@ public class PackageManagerService implements PackageSender, TestUtilityService @Override public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames, int restrictionFlags, int userId) { mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, "setDistractingPackageRestrictionsAsUser"); final int callingUid = Binder.getCallingUid(); if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID && UserHandle.getUserId(callingUid) != userId) { throw new SecurityException("Calling uid " + callingUid + " cannot call for user " + userId); } Objects.requireNonNull(packageNames, "packageNames cannot be null"); final Computer snapshot = snapshotComputer(); if (restrictionFlags != 0 && !mSuspendPackageHelper.isSuspendAllowedForUser(snapshot, userId, callingUid)) { Slog.w(PackageManagerService.TAG, "Cannot restrict packages due to restrictions on user " + userId); return packageNames; } final List<String> changedPackagesList = new ArrayList<>(packageNames.length); final IntArray changedUids = new IntArray(packageNames.length); final List<String> unactionedPackages = new ArrayList<>(packageNames.length); ArraySet<String> changesToCommit = new ArraySet<>(); final boolean[] canRestrict = (restrictionFlags != 0) ? mSuspendPackageHelper.canSuspendPackageForUser(snapshot, packageNames, userId, callingUid) : null; for (int i = 0; i < packageNames.length; i++) { final String packageName = packageNames[i]; final PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName); if (packageState == null || snapshot.shouldFilterApplication(packageState, callingUid, userId)) { Slog.w(PackageManagerService.TAG, "Could not find package setting for package: " + packageName + ". Skipping..."); unactionedPackages.add(packageName); 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); } } commitPackageStateMutation(null, mutator -> { final int size = changesToCommit.size(); for (int index = 0; index < size; index++) { mutator.forPackage(changesToCommit.valueAt(index)) .userState(userId) .setDistractionFlags(restrictionFlags); } }); if (!changedPackagesList.isEmpty()) { final String[] changedPackages = changedPackagesList.toArray( new String[changedPackagesList.size()]); mHandler.post(() -> mBroadcastHelper.sendDistractingPackagesChanged( changedPackages, changedUids.toArray(), userId, restrictionFlags)); scheduleWritePackageRestrictions(userId); } return unactionedPackages.toArray(new String[0]); enforceCanSetDistractingPackageRestrictionsAsUser(snapshot, callingUid, userId, "setDistractingPackageRestrictionsAsUser"); Objects.requireNonNull(packageNames, "packageNames cannot be null"); return mDistractingPackageHelper.setDistractingPackageRestrictionsAsUser(snapshot, packageNames, restrictionFlags, userId, callingUid); } @Override Loading Loading @@ -6093,6 +6012,12 @@ public class PackageManagerService implements PackageSender, TestUtilityService return mSuspendPackageHelper; } @NonNull @Override protected DistractingPackageHelper getDistractingPackageHelper() { return mDistractingPackageHelper; } @NonNull @Override protected ProtectedPackages getProtectedPackages() { Loading
services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java +1 −0 Original line number Diff line number Diff line Loading @@ -115,4 +115,5 @@ public final class PackageManagerServiceTestParams { public ResolveIntentHelper resolveIntentHelper; public DexOptHelper dexOptHelper; public SuspendPackageHelper suspendPackageHelper; public DistractingPackageHelper distractingPackageHelper; }