summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/app/ApplicationPackageManager.java5
-rw-r--r--core/java/android/content/Intent.java11
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl3
-rw-r--r--core/java/android/content/pm/LauncherApps.java4
-rw-r--r--core/java/android/content/pm/PackageManagerInternal.java4
-rw-r--r--core/java/android/content/pm/PackageUserState.java197
-rw-r--r--core/java/com/android/internal/content/PackageMonitor.java9
-rw-r--r--core/proto/android/service/package.proto2
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java5
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java27
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java190
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java46
-rw-r--r--services/core/java/com/android/server/pm/Settings.java132
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartInterceptor.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java137
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java121
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java4
19 files changed, 629 insertions, 277 deletions
diff --git a/api/current.txt b/api/current.txt
index eeaabf661e73..f56400c9a4db 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11392,7 +11392,7 @@ package android.content.pm {
method public abstract void onPackageRemoved(String, android.os.UserHandle);
method public abstract void onPackagesAvailable(String[], android.os.UserHandle, boolean);
method public void onPackagesSuspended(String[], android.os.UserHandle);
- method public void onPackagesSuspended(String[], android.os.UserHandle, @Nullable android.os.Bundle);
+ method @Deprecated public void onPackagesSuspended(String[], android.os.UserHandle, @Nullable android.os.Bundle);
method public abstract void onPackagesUnavailable(String[], android.os.UserHandle, boolean);
method public void onPackagesUnsuspended(String[], android.os.UserHandle);
method public void onShortcutsChanged(@NonNull String, @NonNull java.util.List<android.content.pm.ShortcutInfo>, @NonNull android.os.UserHandle);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index d74399c54bda..a2013075b379 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2414,14 +2414,11 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public Bundle getSuspendedPackageAppExtras() {
- final PersistableBundle extras;
try {
- extras = mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(),
- getUserId());
+ return mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(), getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- return extras != null ? new Bundle(extras.deepCopy()) : null;
}
@Override
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3418b7be42d6..40d9a0dfb095 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2025,17 +2025,6 @@ public class Intent implements Parcelable, Cloneable {
public static final String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED";
/**
- * Intent extra: A {@link Bundle} of extras supplied for the launcher when any packages on
- * device are suspended. Will be sent with {@link #ACTION_PACKAGES_SUSPENDED}.
- *
- * @see PackageManager#isPackageSuspended()
- * @see #ACTION_PACKAGES_SUSPENDED
- *
- * @hide
- */
- public static final String EXTRA_LAUNCHER_EXTRAS = "android.intent.extra.LAUNCHER_EXTRAS";
-
- /**
* Intent extra: ID of the shortcut used to send the share intent. Will be sent with
* {@link #ACTION_SEND}.
*
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c6beee2f898a..4d7c43ace923 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -50,6 +50,7 @@ import android.content.pm.VersionedPackage;
import android.content.pm.dex.IArtManager;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.content.IntentSender;
@@ -280,7 +281,7 @@ interface IPackageManager {
boolean isPackageSuspendedForUser(String packageName, int userId);
- PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId);
+ Bundle getSuspendedPackageAppExtras(String packageName, int userId);
/**
* Backup/restore support - only the system uid may use these.
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index c74daa8eadfc..5650b25d73f0 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -248,7 +248,11 @@ public class LauncherApps {
* system, {@code null} otherwise.
* @see PackageManager#isPackageSuspended()
* @see #getSuspendedPackageLauncherExtras(String, UserHandle)
+ * @deprecated {@code launcherExtras} should be obtained by using
+ * {@link #getSuspendedPackageLauncherExtras(String, UserHandle)}. For all other cases,
+ * {@link #onPackagesSuspended(String[], UserHandle)} should be used.
*/
+ @Deprecated
public void onPackagesSuspended(String[] packageNames, UserHandle user,
@Nullable Bundle launcherExtras) {
onPackagesSuspended(packageNames, user);
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 24ee21360ed8..0a50125a7bb1 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -191,11 +191,13 @@ public abstract class PackageManagerInternal {
* suspended application.
*
* @param suspendedPackage The package that has been suspended.
+ * @param suspendingPackage
* @param userId The user for which to check.
* @return A {@link SuspendDialogInfo} object describing the dialog to be shown.
*/
@Nullable
- public abstract SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, int userId);
+ public abstract SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
+ String suspendingPackage, int userId);
/**
* Gets any distraction flags set via
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 249b6919fc28..5c74efb8ff1b 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -31,6 +31,7 @@ import android.annotation.UnsupportedAppUsage;
import android.os.BaseBundle;
import android.os.Debug;
import android.os.PersistableBundle;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.Slog;
@@ -38,6 +39,11 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
@@ -56,10 +62,7 @@ public class PackageUserState {
public boolean hidden; // Is the app restricted by owner / admin
public int distractionFlags;
public boolean suspended;
- public String suspendingPackage;
- public SuspendDialogInfo dialogInfo;
- public PersistableBundle suspendedAppExtras;
- public PersistableBundle suspendedLauncherExtras;
+ public ArrayMap<String, SuspendParams> suspendParams; // Suspending package to suspend params
public boolean instantApp;
public boolean virtualPreload;
public int enabled;
@@ -95,10 +98,7 @@ public class PackageUserState {
hidden = o.hidden;
distractionFlags = o.distractionFlags;
suspended = o.suspended;
- suspendingPackage = o.suspendingPackage;
- dialogInfo = o.dialogInfo;
- suspendedAppExtras = o.suspendedAppExtras;
- suspendedLauncherExtras = o.suspendedLauncherExtras;
+ suspendParams = new ArrayMap<>(o.suspendParams);
instantApp = o.instantApp;
virtualPreload = o.virtualPreload;
enabled = o.enabled;
@@ -231,19 +231,7 @@ public class PackageUserState {
return false;
}
if (suspended) {
- if (suspendingPackage == null
- || !suspendingPackage.equals(oldState.suspendingPackage)) {
- return false;
- }
- if (!Objects.equals(dialogInfo, oldState.dialogInfo)) {
- return false;
- }
- if (!BaseBundle.kindofEquals(suspendedAppExtras,
- oldState.suspendedAppExtras)) {
- return false;
- }
- if (!BaseBundle.kindofEquals(suspendedLauncherExtras,
- oldState.suspendedLauncherExtras)) {
+ if (!Objects.equals(suspendParams, oldState.suspendParams)) {
return false;
}
}
@@ -308,4 +296,171 @@ public class PackageUserState {
}
return true;
}
+
+ @Override
+ public int hashCode() {
+ int hashCode = Long.hashCode(ceDataInode);
+ hashCode = 31 * hashCode + Boolean.hashCode(installed);
+ hashCode = 31 * hashCode + Boolean.hashCode(stopped);
+ hashCode = 31 * hashCode + Boolean.hashCode(notLaunched);
+ hashCode = 31 * hashCode + Boolean.hashCode(hidden);
+ hashCode = 31 * hashCode + distractionFlags;
+ hashCode = 31 * hashCode + Boolean.hashCode(suspended);
+ hashCode = 31 * hashCode + Objects.hashCode(suspendParams);
+ hashCode = 31 * hashCode + Boolean.hashCode(instantApp);
+ hashCode = 31 * hashCode + Boolean.hashCode(virtualPreload);
+ hashCode = 31 * hashCode + enabled;
+ hashCode = 31 * hashCode + Objects.hashCode(lastDisableAppCaller);
+ hashCode = 31 * hashCode + domainVerificationStatus;
+ hashCode = 31 * hashCode + appLinkGeneration;
+ hashCode = 31 * hashCode + categoryHint;
+ hashCode = 31 * hashCode + installReason;
+ hashCode = 31 * hashCode + Objects.hashCode(disabledComponents);
+ hashCode = 31 * hashCode + Objects.hashCode(enabledComponents);
+ hashCode = 31 * hashCode + Objects.hashCode(harmfulAppWarning);
+ return hashCode;
+ }
+
+ /**
+ * Container to describe suspension parameters.
+ */
+ public static final class SuspendParams {
+ private static final String TAG_DIALOG_INFO = "dialog-info";
+ private static final String TAG_APP_EXTRAS = "app-extras";
+ private static final String TAG_LAUNCHER_EXTRAS = "launcher-extras";
+
+ public SuspendDialogInfo dialogInfo;
+ public PersistableBundle appExtras;
+ public PersistableBundle launcherExtras;
+
+ private SuspendParams() {
+ }
+
+ /**
+ * Returns a {@link SuspendParams} object with the given fields. Returns {@code null} if all
+ * the fields are {@code null}.
+ *
+ * @param dialogInfo
+ * @param appExtras
+ * @param launcherExtras
+ * @return A {@link SuspendParams} object or {@code null}.
+ */
+ public static SuspendParams getInstanceOrNull(SuspendDialogInfo dialogInfo,
+ PersistableBundle appExtras, PersistableBundle launcherExtras) {
+ if (dialogInfo == null && appExtras == null && launcherExtras == null) {
+ return null;
+ }
+ final SuspendParams instance = new SuspendParams();
+ instance.dialogInfo = dialogInfo;
+ instance.appExtras = appExtras;
+ instance.launcherExtras = launcherExtras;
+ return instance;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof SuspendParams)) {
+ return false;
+ }
+ final SuspendParams other = (SuspendParams) obj;
+ if (!Objects.equals(dialogInfo, other.dialogInfo)) {
+ return false;
+ }
+ if (!BaseBundle.kindofEquals(appExtras, other.appExtras)) {
+ return false;
+ }
+ if (!BaseBundle.kindofEquals(launcherExtras, other.launcherExtras)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = Objects.hashCode(dialogInfo);
+ hashCode = 31 * hashCode + ((appExtras != null) ? appExtras.size() : 0);
+ hashCode = 31 * hashCode + ((launcherExtras != null) ? launcherExtras.size() : 0);
+ return hashCode;
+ }
+
+ /**
+ * Serializes this object into an xml format
+ * @param out the {@link XmlSerializer} object
+ * @throws IOException
+ */
+ public void saveToXml(XmlSerializer out) throws IOException {
+ if (dialogInfo != null) {
+ out.startTag(null, TAG_DIALOG_INFO);
+ dialogInfo.saveToXml(out);
+ out.endTag(null, TAG_DIALOG_INFO);
+ }
+ if (appExtras != null) {
+ out.startTag(null, TAG_APP_EXTRAS);
+ try {
+ appExtras.saveToXml(out);
+ } catch (XmlPullParserException e) {
+ Slog.e(LOG_TAG, "Exception while trying to write appExtras."
+ + " Will be lost on reboot", e);
+ }
+ out.endTag(null, TAG_APP_EXTRAS);
+ }
+ if (launcherExtras != null) {
+ out.startTag(null, TAG_LAUNCHER_EXTRAS);
+ try {
+ launcherExtras.saveToXml(out);
+ } catch (XmlPullParserException e) {
+ Slog.e(LOG_TAG, "Exception while trying to write launcherExtras."
+ + " Will be lost on reboot", e);
+ }
+ out.endTag(null, TAG_LAUNCHER_EXTRAS);
+ }
+ }
+
+ /**
+ * Parses this object from the xml format. Returns {@code null} if no object related
+ * information could be read.
+ * @param in the reader
+ * @return
+ */
+ public static SuspendParams restoreFromXml(XmlPullParser in) throws IOException {
+ SuspendDialogInfo readDialogInfo = null;
+ PersistableBundle readAppExtras = null;
+ PersistableBundle readLauncherExtras = null;
+
+ final int currentDepth = in.getDepth();
+ int type;
+ try {
+ while ((type = in.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || in.getDepth() > currentDepth)) {
+ if (type == XmlPullParser.END_TAG
+ || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ switch (in.getName()) {
+ case TAG_DIALOG_INFO:
+ readDialogInfo = SuspendDialogInfo.restoreFromXml(in);
+ break;
+ case TAG_APP_EXTRAS:
+ readAppExtras = PersistableBundle.restoreFromXml(in);
+ break;
+ case TAG_LAUNCHER_EXTRAS:
+ readLauncherExtras = PersistableBundle.restoreFromXml(in);
+ break;
+ default:
+ Slog.w(LOG_TAG, "Unknown tag " + in.getName()
+ + " in SuspendParams. Ignoring");
+ break;
+ }
+ }
+ } catch (XmlPullParserException e) {
+ Slog.e(LOG_TAG, "Exception while trying to parse SuspendParams,"
+ + " some fields may default", e);
+ }
+ return getInstanceOrNull(readDialogInfo, readAppExtras, readLauncherExtras);
+ }
+ }
}
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index c928f3f39f03..d6dcb29e0682 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -22,11 +22,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
-import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.util.Slog;
+
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.Preconditions;
@@ -203,10 +203,6 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
public void onPackagesSuspended(String[] packages) {
}
- public void onPackagesSuspended(String[] packages, Bundle launcherExtras) {
- onPackagesSuspended(packages);
- }
-
public void onPackagesUnsuspended(String[] packages) {
}
@@ -446,9 +442,8 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
}
} else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) {
String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
- final Bundle launcherExtras = intent.getBundleExtra(Intent.EXTRA_LAUNCHER_EXTRAS);
mSomePackagesChanged = true;
- onPackagesSuspended(pkgList, launcherExtras);
+ onPackagesSuspended(pkgList);
} else if (Intent.ACTION_PACKAGES_UNSUSPENDED.equals(action)) {
String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
mSomePackagesChanged = true;
diff --git a/core/proto/android/service/package.proto b/core/proto/android/service/package.proto
index 6ffa0c943037..301fa13ce4d8 100644
--- a/core/proto/android/service/package.proto
+++ b/core/proto/android/service/package.proto
@@ -110,7 +110,7 @@ message PackageProto {
optional bool is_launched = 6;
optional EnabledState enabled_state = 7;
optional string last_disabled_app_caller = 8;
- optional string suspending_package = 9;
+ repeated string suspending_package = 9;
optional int32 distraction_flags = 10;
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index fea4e9047f83..81ce359cc078 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -631,8 +631,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
onClickIntent = mDevicePolicyManagerInternal.createShowAdminSupportIntent(
providerUserId, true);
} else {
- final SuspendDialogInfo dialogInfo = mPackageManagerInternal
- .getSuspendedDialogInfo(providerPackage, providerUserId);
+ final SuspendDialogInfo dialogInfo =
+ mPackageManagerInternal.getSuspendedDialogInfo(providerPackage,
+ suspendingPackage, providerUserId);
onClickIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(
providerPackage, suspendingPackage, dialogInfo, providerUserId);
}
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 3464cab99d93..2b6c347fe726 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -62,6 +62,7 @@ import android.os.UserManager;
import android.os.UserManagerInternal;
import android.provider.Settings;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -1024,8 +1025,22 @@ public class LauncherAppsService extends SystemService {
}
@Override
- public void onPackagesSuspended(String[] packages, Bundle launcherExtras) {
+ public void onPackagesSuspended(String[] packages) {
UserHandle user = new UserHandle(getChangingUserId());
+ PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+ final ArrayList<Pair<String, Bundle>> packagesWithExtras = new ArrayList<>();
+ final ArrayList<String> packagesWithoutExtras = new ArrayList<>();
+ for (String pkg : packages) {
+ final Bundle launcherExtras = pmi.getSuspendedPackageLauncherExtras(pkg,
+ user.getIdentifier());
+ if (launcherExtras != null) {
+ packagesWithExtras.add(new Pair<>(pkg, launcherExtras));
+ } else {
+ packagesWithoutExtras.add(pkg);
+ }
+ }
+ final String[] packagesNullExtras = packagesWithoutExtras.toArray(
+ new String[packagesWithoutExtras.size()]);
final int n = mListeners.beginBroadcast();
try {
for (int i = 0; i < n; i++) {
@@ -1033,7 +1048,13 @@ public class LauncherAppsService extends SystemService {
BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue;
try {
- listener.onPackagesSuspended(user, packages, launcherExtras);
+ listener.onPackagesSuspended(user, packagesNullExtras, null);
+ for (int idx = 0; idx < packagesWithExtras.size(); idx++) {
+ Pair<String, Bundle> packageExtraPair = packagesWithExtras.get(idx);
+ listener.onPackagesSuspended(user,
+ new String[]{packageExtraPair.first},
+ packageExtraPair.second);
+ }
} catch (RemoteException re) {
Slog.d(TAG, "Callback failed ", re);
}
@@ -1041,8 +1062,6 @@ public class LauncherAppsService extends SystemService {
} finally {
mListeners.finishBroadcast();
}
-
- super.onPackagesSuspended(packages, launcherExtras);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index fe3d2c8fa981..3c6016f8afc3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -372,7 +372,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
-import java.util.function.Predicate;
/**
* Keep track of all those APKs everywhere.
@@ -12665,14 +12664,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
private void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
- boolean suspended, PersistableBundle launcherExtras) {
+ boolean suspended) {
final Bundle extras = new Bundle(3);
extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
- if (launcherExtras != null) {
- extras.putBundle(Intent.EXTRA_LAUNCHER_EXTRAS,
- new Bundle(launcherExtras.deepCopy()));
- }
sendPackageBroadcast(
suspended ? Intent.ACTION_PACKAGES_SUSPENDED
: Intent.ACTION_PACKAGES_UNSUSPENDED,
@@ -12937,8 +12932,6 @@ public class PackageManagerService extends IPackageManager.Stub
if (ownerUid == callingUid) {
return;
}
- throw new UnsupportedOperationException("Cannot suspend/unsuspend packages. User "
- + userId + " has an active DO or PO");
}
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
@@ -12946,6 +12939,7 @@ public class PackageManagerService extends IPackageManager.Stub
final int packageUid = getPackageUid(callingPackage, 0, userId);
final boolean allowedPackageUid = packageUid == callingUid;
+ // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
final boolean allowedShell = callingUid == SHELL_UID
&& UserHandle.isSameApp(packageUid, callingUid);
@@ -12996,20 +12990,27 @@ public class PackageManagerService extends IPackageManager.Stub
unactionedPackages.add(packageName);
continue;
}
+ boolean packageUnsuspended;
synchronized (mLock) {
- pkgSetting.setSuspended(suspended, callingPackage, dialogInfo, appExtras,
- launcherExtras, userId);
+ if (suspended) {
+ pkgSetting.addOrUpdateSuspension(callingPackage, dialogInfo, appExtras,
+ launcherExtras, userId);
+ } else {
+ pkgSetting.removeSuspension(callingPackage, userId);
+ }
+ packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
+ }
+ if (suspended || packageUnsuspended) {
+ changedPackagesList.add(packageName);
+ changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
}
- changedPackagesList.add(packageName);
- changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
}
if (!changedPackagesList.isEmpty()) {
final String[] changedPackages = changedPackagesList.toArray(
new String[changedPackagesList.size()]);
- sendPackagesSuspendedForUser(
- changedPackages, changedUids.toArray(), userId, suspended, launcherExtras);
- sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, appExtras, userId);
+ sendPackagesSuspendedForUser(changedPackages, changedUids.toArray(), userId, suspended);
+ sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
synchronized (mLock) {
scheduleWritePackageRestrictionsLocked(userId);
}
@@ -13018,38 +13019,40 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId) {
+ public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
final int callingUid = Binder.getCallingUid();
if (getPackageUid(packageName, 0, userId) != callingUid) {
throw new SecurityException("Calling package " + packageName
+ " does not belong to calling uid " + callingUid);
}
+ return getSuspendedPackageAppExtrasInternal(packageName, userId);
+ }
+
+ private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) {
synchronized (mLock) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
+ if (ps == null) {
throw new IllegalArgumentException("Unknown target package: " + packageName);
}
- final PackageUserState packageUserState = ps.readUserState(userId);
- if (packageUserState.suspended) {
- return packageUserState.suspendedAppExtras;
+ final PackageUserState pus = ps.readUserState(userId);
+ final Bundle allExtras = new Bundle();
+ if (pus.suspended) {
+ for (int i = 0; i < pus.suspendParams.size(); i++) {
+ final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
+ if (params != null && params.appExtras != null) {
+ allExtras.putAll(params.appExtras);
+ }
+ }
}
- return null;
+ return (allExtras.size() > 0) ? allExtras : null;
}
}
private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
- PersistableBundle appExtras, int userId) {
- final String action;
- final Bundle intentExtras = new Bundle();
- if (suspended) {
- action = Intent.ACTION_MY_PACKAGE_SUSPENDED;
- if (appExtras != null) {
- final Bundle bundledAppExtras = new Bundle(appExtras.deepCopy());
- intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, bundledAppExtras);
- }
- } else {
- action = Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
- }
+ int userId) {
+ final String action = suspended
+ ? Intent.ACTION_MY_PACKAGE_SUSPENDED
+ : Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
mHandler.post(() -> {
try {
final IActivityManager am = ActivityManager.getService();
@@ -13060,6 +13063,16 @@ public class PackageManagerService extends IPackageManager.Stub
}
final int[] targetUserIds = new int[] {userId};
for (String packageName : affectedPackages) {
+ final Bundle appExtras = suspended
+ ? getSuspendedPackageAppExtrasInternal(packageName, userId)
+ : null;
+ final Bundle intentExtras;
+ if (appExtras != null) {
+ intentExtras = new Bundle(1);
+ intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras);
+ } else {
+ intentExtras = null;
+ }
doSendBroadcast(am, action, null, intentExtras,
Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
targetUserIds, false);
@@ -13092,57 +13105,32 @@ public class PackageManagerService extends IPackageManager.Stub
* <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
* synchronously
*
- * @param packageName The package holding {@link Manifest.permission#SUSPEND_APPS} permission
- * @param affectedUser The user for which the changes are taking place.
- */
- void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
- final int[] userIds = (affectedUser == UserHandle.USER_ALL) ? mUserManager.getUserIds()
- : new int[] {affectedUser};
- for (int userId : userIds) {
- unsuspendForSuspendingPackages(packageName::equals, userId);
- }
- }
-
- /**
- * Immediately unsuspends any packages in the given users not suspended by the platform or root.
- * To be called when a profile owner or a device owner is added.
- *
- * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
- * synchronously
- *
- * @param userIds The users for which to unsuspend packages
+ * @param suspendingPackage The suspending package
+ * @param userId The user for which the changes are taking place.
*/
- void unsuspendForNonSystemSuspendingPackages(ArraySet<Integer> userIds) {
- final int sz = userIds.size();
- for (int i = 0; i < sz; i++) {
- unsuspendForSuspendingPackages(
- (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
- userIds.valueAt(i));
- }
- }
-
- private void unsuspendForSuspendingPackages(Predicate<String> packagePredicate, int userId) {
- final List<String> affectedPackages = new ArrayList<>();
- final IntArray affectedUids = new IntArray();
+ private void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
+ final List<String> unsuspendedPackages = new ArrayList<>();
+ final IntArray unsuspendedUids = new IntArray();
synchronized (mLock) {
for (PackageSetting ps : mSettings.mPackages.values()) {
final PackageUserState pus = ps.readUserState(userId);
- if (pus.suspended && packagePredicate.test(pus.suspendingPackage)) {
- ps.setSuspended(false, null, null, null, null, userId);
- affectedPackages.add(ps.name);
- affectedUids.add(UserHandle.getUid(userId, ps.getAppId()));
+ if (pus.suspended) {
+ ps.removeSuspension(suspendingPackage, userId);
+ if (!ps.getSuspended(userId)) {
+ unsuspendedPackages.add(ps.name);
+ unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId()));
+ }
}
}
}
- if (!affectedPackages.isEmpty()) {
- final String[] packageArray = affectedPackages.toArray(
- new String[affectedPackages.size()]);
- sendMyPackageSuspendedOrUnsuspended(packageArray, false, null, userId);
- sendPackagesSuspendedForUser(
- packageArray, affectedUids.toArray(), userId, false, null);
- // Write package restrictions immediately to avoid an inconsistent state.
- mSettings.writePackageRestrictionsLPr(userId);
+ if (!unsuspendedPackages.isEmpty()) {
+ final String[] packageArray = unsuspendedPackages.toArray(
+ new String[unsuspendedPackages.size()]);
+ sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
+ sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false);
}
+ // Write package restrictions immediately to avoid an inconsistent state.
+ mSettings.writePackageRestrictionsLPr(userId);
}
@Override
@@ -18712,10 +18700,7 @@ public class PackageManagerService extends IPackageManager.Stub
false /*hidden*/,
0 /*distractionFlags*/,
false /*suspended*/,
- null /*suspendingPackage*/,
- null /*dialogInfo*/,
- null /*suspendedAppExtras*/,
- null /*suspendedLauncherExtras*/,
+ null /*suspendParams*/,
false /*instantApp*/,
false /*virtualPreload*/,
null /*lastDisableAppCaller*/,
@@ -23217,11 +23202,21 @@ public class PackageManagerService extends IPackageManager.Stub
public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
synchronized (mLock) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
- PersistableBundle launcherExtras = null;
+ final Bundle allExtras = new Bundle();
if (ps != null) {
- launcherExtras = ps.readUserState(userId).suspendedLauncherExtras;
+ final PackageUserState pus = ps.readUserState(userId);
+ if (pus.suspended) {
+ for (int i = 0; i < pus.suspendParams.size(); i++) {
+ final PackageUserState.SuspendParams params =
+ pus.suspendParams.valueAt(i);
+ if (params != null && params.launcherExtras != null) {
+ allExtras.putAll(params.launcherExtras);
+ }
+ }
+ }
+
}
- return (launcherExtras != null) ? new Bundle(launcherExtras.deepCopy()) : null;
+ return (allExtras.size() > 0) ? allExtras : null;
}
}
@@ -23237,16 +23232,38 @@ public class PackageManagerService extends IPackageManager.Stub
public String getSuspendingPackage(String suspendedPackage, int userId) {
synchronized (mLock) {
final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
- return (ps != null) ? ps.readUserState(userId).suspendingPackage : null;
+ if (ps != null) {
+ final PackageUserState pus = ps.readUserState(userId);
+ if (pus.suspended) {
+ String suspendingPackage = null;
+ for (int i = 0; i < pus.suspendParams.size(); i++) {
+ suspendingPackage = pus.suspendParams.keyAt(i);
+ if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
+ return suspendingPackage;
+ }
+ }
+ return suspendingPackage;
+ }
+ }
+ return null;
}
}
@Override
- public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, int userId) {
+ public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
+ String suspendingPackage, int userId) {
synchronized (mLock) {
final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
- return (ps != null) ? ps.readUserState(userId).dialogInfo : null;
+ if (ps != null) {
+ final PackageUserState pus = ps.readUserState(userId);
+ if (pus.suspended) {
+ final PackageUserState.SuspendParams suspendParams =
+ pus.suspendParams.get(suspendingPackage);
+ return (suspendParams != null) ? suspendParams.dialogInfo : null;
+ }
+ }
}
+ return null;
}
@Override
@@ -23323,7 +23340,6 @@ public class PackageManagerService extends IPackageManager.Stub
usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
}
}
- unsuspendForNonSystemSuspendingPackages(usersWithPoOrDo);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index fe529a152364..64391c30fa5a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -2044,7 +2044,9 @@ class PackageManagerShellCommand extends ShellCommand {
}
try {
mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
- appExtras, launcherExtras, info, callingPackage, userId);
+ ((appExtras.size() > 0) ? appExtras : null),
+ ((launcherExtras.size() > 0) ? launcherExtras : null),
+ info, callingPackage, userId);
pw.println("Package " + packageName + " new suspended state: "
+ mInterface.isPackageSuspendedForUser(packageName, userId));
return 0;
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 029673ffd87b..0da6b549f296 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -29,6 +29,7 @@ import android.content.pm.Signature;
import android.content.pm.SuspendDialogInfo;
import android.os.PersistableBundle;
import android.service.pm.PackageProto;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
@@ -405,14 +406,28 @@ public abstract class PackageSettingBase extends SettingBase {
return readUserState(userId).suspended;
}
- void setSuspended(boolean suspended, String suspendingPackage, SuspendDialogInfo dialogInfo,
+ void addOrUpdateSuspension(String suspendingPackage, SuspendDialogInfo dialogInfo,
PersistableBundle appExtras, PersistableBundle launcherExtras, int userId) {
final PackageUserState existingUserState = modifyUserState(userId);
- existingUserState.suspended = suspended;
- existingUserState.suspendingPackage = suspended ? suspendingPackage : null;
- existingUserState.dialogInfo = suspended ? dialogInfo : null;
- existingUserState.suspendedAppExtras = suspended ? appExtras : null;
- existingUserState.suspendedLauncherExtras = suspended ? launcherExtras : null;
+ final PackageUserState.SuspendParams newSuspendParams =
+ PackageUserState.SuspendParams.getInstanceOrNull(dialogInfo, appExtras,
+ launcherExtras);
+ if (existingUserState.suspendParams == null) {
+ existingUserState.suspendParams = new ArrayMap<>();
+ }
+ existingUserState.suspendParams.put(suspendingPackage, newSuspendParams);
+ existingUserState.suspended = true;
+ }
+
+ void removeSuspension(String suspendingPackage, int userId) {
+ final PackageUserState existingUserState = modifyUserState(userId);
+ if (existingUserState.suspendParams != null) {
+ existingUserState.suspendParams.remove(suspendingPackage);
+ if (existingUserState.suspendParams.size() == 0) {
+ existingUserState.suspendParams = null;
+ }
+ }
+ existingUserState.suspended = (existingUserState.suspendParams != null);
}
public boolean getInstantApp(int userId) {
@@ -433,9 +448,7 @@ public abstract class PackageSettingBase extends SettingBase {
void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
boolean notLaunched, boolean hidden, int distractionFlags, boolean suspended,
- String suspendingPackage,
- SuspendDialogInfo dialogInfo, PersistableBundle suspendedAppExtras,
- PersistableBundle suspendedLauncherExtras, boolean instantApp,
+ ArrayMap<String, PackageUserState.SuspendParams> suspendParams, boolean instantApp,
boolean virtualPreload, String lastDisableAppCaller,
ArraySet<String> enabledComponents, ArraySet<String> disabledComponents,
int domainVerifState, int linkGeneration, int installReason,
@@ -449,10 +462,7 @@ public abstract class PackageSettingBase extends SettingBase {
state.hidden = hidden;
state.distractionFlags = distractionFlags;
state.suspended = suspended;
- state.suspendingPackage = suspendingPackage;
- state.dialogInfo = dialogInfo;
- state.suspendedAppExtras = suspendedAppExtras;
- state.suspendedLauncherExtras = suspendedLauncherExtras;
+ state.suspendParams = suspendParams;
state.lastDisableAppCaller = lastDisableAppCaller;
state.enabledComponents = enabledComponents;
state.disabledComponents = disabledComponents;
@@ -467,9 +477,8 @@ public abstract class PackageSettingBase extends SettingBase {
void setUserState(int userId, PackageUserState otherState) {
setUserState(userId, otherState.ceDataInode, otherState.enabled, otherState.installed,
otherState.stopped, otherState.notLaunched, otherState.hidden,
- otherState.distractionFlags, otherState.suspended, otherState.suspendingPackage,
- otherState.dialogInfo, otherState.suspendedAppExtras,
- otherState.suspendedLauncherExtras, otherState.instantApp,
+ otherState.distractionFlags, otherState.suspended, otherState.suspendParams,
+ otherState.instantApp,
otherState.virtualPreload, otherState.lastDisableAppCaller,
otherState.enabledComponents, otherState.disabledComponents,
otherState.domainVerificationStatus, otherState.appLinkGeneration,
@@ -633,7 +642,10 @@ public abstract class PackageSettingBase extends SettingBase {
proto.write(PackageProto.UserInfoProto.DISTRACTION_FLAGS, state.distractionFlags);
proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended);
if (state.suspended) {
- proto.write(PackageProto.UserInfoProto.SUSPENDING_PACKAGE, state.suspendingPackage);
+ for (int j = 0; j < state.suspendParams.size(); j++) {
+ proto.write(PackageProto.UserInfoProto.SUSPENDING_PACKAGE,
+ state.suspendParams.keyAt(j));
+ }
}
proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped);
proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 597246884ca5..5f9cdb57e5f1 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -203,9 +203,22 @@ public final class Settings {
private static final String TAG_DEFAULT_BROWSER = "default-browser";
private static final String TAG_DEFAULT_DIALER = "default-dialer";
private static final String TAG_VERSION = "version";
+ /**
+ * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams}
+ */
+ @Deprecated
private static final String TAG_SUSPENDED_DIALOG_INFO = "suspended-dialog-info";
+ /**
+ * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams}
+ */
+ @Deprecated
private static final String TAG_SUSPENDED_APP_EXTRAS = "suspended-app-extras";
+ /**
+ * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams}
+ */
+ @Deprecated
private static final String TAG_SUSPENDED_LAUNCHER_EXTRAS = "suspended-launcher-extras";
+ private static final String TAG_SUSPEND_PARAMS = "suspend-params";
public static final String ATTR_NAME = "name";
public static final String ATTR_PACKAGE = "package";
@@ -658,10 +671,7 @@ public final class Settings {
false /*hidden*/,
0 /*distractionFlags*/,
false /*suspended*/,
- null /*suspendingPackage*/,
- null /*dialogInfo*/,
- null /*suspendedAppExtras*/,
- null /*suspendedLauncherExtras*/,
+ null /*suspendParams*/,
instantApp,
virtualPreload,
null /*lastDisableAppCaller*/,
@@ -1548,10 +1558,7 @@ public final class Settings {
false /*hidden*/,
0 /*distractionFlags*/,
false /*suspended*/,
- null /*suspendingPackage*/,
- null /*dialogInfo*/,
- null /*suspendedAppExtras*/,
- null /*suspendedLauncherExtras*/,
+ null /*suspendParams*/,
false /*instantApp*/,
false /*virtualPreload*/,
null /*lastDisableAppCaller*/,
@@ -1626,12 +1633,12 @@ public final class Settings {
ATTR_DISTRACTION_FLAGS, 0);
final boolean suspended = XmlUtils.readBooleanAttribute(parser, ATTR_SUSPENDED,
false);
- String suspendingPackage = parser.getAttributeValue(null,
+ String oldSuspendingPackage = parser.getAttributeValue(null,
ATTR_SUSPENDING_PACKAGE);
final String dialogMessage = parser.getAttributeValue(null,
ATTR_SUSPEND_DIALOG_MESSAGE);
- if (suspended && suspendingPackage == null) {
- suspendingPackage = PLATFORM_PACKAGE_NAME;
+ if (suspended && oldSuspendingPackage == null) {
+ oldSuspendingPackage = PLATFORM_PACKAGE_NAME;
}
final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser,
@@ -1661,9 +1668,10 @@ public final class Settings {
ArraySet<String> disabledComponents = null;
PersistableBundle suspendedAppExtras = null;
PersistableBundle suspendedLauncherExtras = null;
- SuspendDialogInfo suspendDialogInfo = null;
+ SuspendDialogInfo oldSuspendDialogInfo = null;
int packageDepth = parser.getDepth();
+ ArrayMap<String, PackageUserState.SuspendParams> suspendParamsMap = null;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > packageDepth)) {
@@ -1685,26 +1693,48 @@ public final class Settings {
suspendedLauncherExtras = PersistableBundle.restoreFromXml(parser);
break;
case TAG_SUSPENDED_DIALOG_INFO:
- suspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser);
+ oldSuspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser);
+ break;
+ case TAG_SUSPEND_PARAMS:
+ final String suspendingPackage = parser.getAttributeValue(null,
+ ATTR_SUSPENDING_PACKAGE);
+ if (suspendingPackage == null) {
+ Slog.wtf(TAG, "No suspendingPackage found inside tag "
+ + TAG_SUSPEND_PARAMS);
+ continue;
+ }
+ if (suspendParamsMap == null) {
+ suspendParamsMap = new ArrayMap<>();
+ }
+ suspendParamsMap.put(suspendingPackage,
+ PackageUserState.SuspendParams.restoreFromXml(parser));
break;
default:
Slog.wtf(TAG, "Unknown tag " + parser.getName() + " under tag "
+ TAG_PACKAGE);
}
}
- if (suspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) {
- suspendDialogInfo = new SuspendDialogInfo.Builder()
+ if (oldSuspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) {
+ oldSuspendDialogInfo = new SuspendDialogInfo.Builder()
.setMessage(dialogMessage)
.build();
}
+ if (suspended && suspendParamsMap == null) {
+ final PackageUserState.SuspendParams suspendParams =
+ PackageUserState.SuspendParams.getInstanceOrNull(
+ oldSuspendDialogInfo,
+ suspendedAppExtras,
+ suspendedLauncherExtras);
+ suspendParamsMap = new ArrayMap<>();
+ suspendParamsMap.put(oldSuspendingPackage, suspendParams);
+ }
if (blockUninstall) {
setBlockUninstallLPw(userId, name, true);
}
ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
- hidden, distractionFlags, suspended, suspendingPackage,
- suspendDialogInfo,
- suspendedAppExtras, suspendedLauncherExtras, instantApp, virtualPreload,
+ hidden, distractionFlags, suspended, suspendParamsMap,
+ instantApp, virtualPreload,
enabledCaller, enabledComponents, disabledComponents, verifState,
linkGeneration, installReason, harmfulAppWarning);
} else if (tagName.equals("preferred-activities")) {
@@ -2004,35 +2034,6 @@ public final class Settings {
}
if (ustate.suspended) {
serializer.attribute(null, ATTR_SUSPENDED, "true");
- if (ustate.suspendingPackage != null) {
- serializer.attribute(null, ATTR_SUSPENDING_PACKAGE,
- ustate.suspendingPackage);
- }
- if (ustate.dialogInfo != null) {
- serializer.startTag(null, TAG_SUSPENDED_DIALOG_INFO);
- ustate.dialogInfo.saveToXml(serializer);
- serializer.endTag(null, TAG_SUSPENDED_DIALOG_INFO);
- }
- if (ustate.suspendedAppExtras != null) {
- serializer.startTag(null, TAG_SUSPENDED_APP_EXTRAS);
- try {
- ustate.suspendedAppExtras.saveToXml(serializer);
- } catch (XmlPullParserException xmle) {
- Slog.wtf(TAG, "Exception while trying to write suspendedAppExtras for "
- + pkg + ". Will be lost on reboot", xmle);
- }
- serializer.endTag(null, TAG_SUSPENDED_APP_EXTRAS);
- }
- if (ustate.suspendedLauncherExtras != null) {
- serializer.startTag(null, TAG_SUSPENDED_LAUNCHER_EXTRAS);
- try {
- ustate.suspendedLauncherExtras.saveToXml(serializer);
- } catch (XmlPullParserException xmle) {
- Slog.wtf(TAG, "Exception while trying to write suspendedLauncherExtras"
- + " for " + pkg + ". Will be lost on reboot", xmle);
- }
- serializer.endTag(null, TAG_SUSPENDED_LAUNCHER_EXTRAS);
- }
}
if (ustate.instantApp) {
serializer.attribute(null, ATTR_INSTANT_APP, "true");
@@ -2065,6 +2066,19 @@ public final class Settings {
serializer.attribute(null, ATTR_HARMFUL_APP_WARNING,
ustate.harmfulAppWarning);
}
+ if (ustate.suspended) {
+ for (int i = 0; i < ustate.suspendParams.size(); i++) {
+ final String suspendingPackage = ustate.suspendParams.keyAt(i);
+ serializer.startTag(null, TAG_SUSPEND_PARAMS);
+ serializer.attribute(null, ATTR_SUSPENDING_PACKAGE, suspendingPackage);
+ final PackageUserState.SuspendParams params =
+ ustate.suspendParams.valueAt(i);
+ if (params != null) {
+ params.saveToXml(serializer);
+ }
+ serializer.endTag(null, TAG_SUSPEND_PARAMS);
+ }
+ }
if (!ArrayUtils.isEmpty(ustate.enabledComponents)) {
serializer.startTag(null, TAG_ENABLED_COMPONENTS);
for (final String name : ustate.enabledComponents) {
@@ -4755,13 +4769,6 @@ public final class Settings {
pw.print(ps.getHidden(user.id));
pw.print(" suspended=");
pw.print(ps.getSuspended(user.id));
- if (ps.getSuspended(user.id)) {
- final PackageUserState pus = ps.readUserState(user.id);
- pw.print(" suspendingPackage=");
- pw.print(pus.suspendingPackage);
- pw.print(" dialogInfo=");
- pw.print(pus.dialogInfo);
- }
pw.print(" stopped=");
pw.print(ps.getStopped(user.id));
pw.print(" notLaunched=");
@@ -4773,6 +4780,23 @@ public final class Settings {
pw.print(" virtual=");
pw.println(ps.getVirtulalPreload(user.id));
+ if (ps.getSuspended(user.id)) {
+ pw.print(prefix);
+ pw.println(" Suspend params:");
+ final PackageUserState pus = ps.readUserState(user.id);
+ for (int i = 0; i < pus.suspendParams.size(); i++) {
+ pw.print(prefix);
+ pw.print(" suspendingPackage=");
+ pw.print(pus.suspendParams.keyAt(i));
+ final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
+ if (params != null) {
+ pw.print(" dialogInfo=");
+ pw.print(params.dialogInfo);
+ }
+ pw.println();
+ }
+ }
+
String[] overlayPaths = ps.getOverlayPaths(user.id);
if (overlayPaths != null && overlayPaths.length > 0) {
pw.print(prefix); pw.println(" overlay paths:");
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 9d08e10c6dea..cc69b5a7205f 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -249,7 +249,8 @@ class ActivityStartInterceptor {
if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
return interceptSuspendedByAdminPackage();
}
- final SuspendDialogInfo dialogInfo = pmi.getSuspendedDialogInfo(suspendedPackage, mUserId);
+ final SuspendDialogInfo dialogInfo = pmi.getSuspendedDialogInfo(suspendedPackage,
+ suspendingPackage, mUserId);
mIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(suspendedPackage,
suspendingPackage, dialogInfo, mUserId);
mCallingPid = mRealCallingPid;
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 3fe9b52b8415..15032c5c5cbb 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -20,8 +20,8 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.res.Resources.ID_NULL;
-import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
@@ -75,10 +75,11 @@ import java.util.List;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class PackageManagerSettingsTests {
+ private static final String TAG = "PackageManagerSettingsTests";
+ private static final String PACKAGE_NAME_1 = "com.android.app1";
private static final String PACKAGE_NAME_2 = "com.android.app2";
private static final String PACKAGE_NAME_3 = "com.android.app3";
- private static final String PACKAGE_NAME_1 = "com.android.app1";
- public static final String TAG = "PackageManagerSettingsTests";
+ private static final int TEST_RESOURCE_ID = 2131231283;
@Mock
PermissionSettings mPermissionSettings;
@@ -158,7 +159,7 @@ public class PackageManagerSettingsTests {
assertThat(ps.getEnabled(1), is(COMPONENT_ENABLED_STATE_DEFAULT));
}
- private PersistableBundle getPersistableBundle(String packageName, long longVal,
+ private static PersistableBundle createPersistableBundle(String packageName, long longVal,
double doubleVal, boolean boolVal, String textVal) {
final PersistableBundle bundle = new PersistableBundle();
bundle.putString(packageName + ".TEXT_VALUE", textVal);
@@ -169,8 +170,8 @@ public class PackageManagerSettingsTests {
}
@Test
- public void testReadPackageRestrictions_oldSuspendInfo() {
- writePackageRestrictions_oldSuspendInfoXml(0);
+ public void testReadPackageRestrictions_noSuspendingPackage() {
+ writePackageRestrictions_noSuspendingPackageXml(0);
final Object lock = new Object();
final Context context = InstrumentationRegistry.getTargetContext();
final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, lock);
@@ -181,26 +182,61 @@ public class PackageManagerSettingsTests {
final PackageSetting ps1 = settingsUnderTest.mPackages.get(PACKAGE_NAME_1);
final PackageUserState packageUserState1 = ps1.readUserState(0);
assertThat(packageUserState1.suspended, is(true));
- assertThat("android".equals(packageUserState1.suspendingPackage), is(true));
+ assertThat(packageUserState1.suspendParams.size(), is(1));
+ assertThat(packageUserState1.suspendParams.keyAt(0), is("android"));
+ assertThat(packageUserState1.suspendParams.valueAt(0), is(nullValue()));
final PackageSetting ps2 = settingsUnderTest.mPackages.get(PACKAGE_NAME_2);
final PackageUserState packageUserState2 = ps2.readUserState(0);
assertThat(packageUserState2.suspended, is(false));
- assertThat(packageUserState2.suspendingPackage, is(nullValue()));
+ assertThat(packageUserState2.suspendParams, is(nullValue()));
}
@Test
- public void testReadWritePackageRestrictions_newSuspendInfo() {
+ public void testReadPackageRestrictions_noSuspendParamsMap() {
+ writePackageRestrictions_noSuspendParamsMapXml(0);
+ final Object lock = new Object();
+ final Context context = InstrumentationRegistry.getTargetContext();
+ final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, lock);
+ settingsUnderTest.mPackages.put(PACKAGE_NAME_1, createPackageSetting(PACKAGE_NAME_1));
+ settingsUnderTest.readPackageRestrictionsLPr(0);
+
+ final PackageSetting ps1 = settingsUnderTest.mPackages.get(PACKAGE_NAME_1);
+ final PackageUserState packageUserState1 = ps1.readUserState(0);
+ assertThat(packageUserState1.suspended, is(true));
+ assertThat(packageUserState1.suspendParams.size(), is(1));
+ assertThat(packageUserState1.suspendParams.keyAt(0), is(PACKAGE_NAME_3));
+ final PackageUserState.SuspendParams params = packageUserState1.suspendParams.valueAt(0);
+ assertThat(params, is(notNullValue()));
+ assertThat(params.appExtras.size(), is(1));
+ assertThat(params.appExtras.getString("app_extra_string"), is("value"));
+ assertThat(params.launcherExtras.size(), is(1));
+ assertThat(params.launcherExtras.getLong("launcher_extra_long"), is(4L));
+ assertThat(params.dialogInfo, is(notNullValue()));
+ assertThat(params.dialogInfo.getDialogMessage(), is("Dialog Message"));
+ assertThat(params.dialogInfo.getTitleResId(), is(ID_NULL));
+ assertThat(params.dialogInfo.getIconResId(), is(TEST_RESOURCE_ID));
+ assertThat(params.dialogInfo.getNeutralButtonTextResId(), is(ID_NULL));
+ assertThat(params.dialogInfo.getDialogMessageResId(), is(ID_NULL));
+ }
+
+ @Test
+ public void testReadWritePackageRestrictions_suspendInfo() {
final Context context = InstrumentationRegistry.getTargetContext();
final Settings settingsUnderTest = new Settings(context.getFilesDir(), null, new Object());
final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1);
final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2);
final PackageSetting ps3 = createPackageSetting(PACKAGE_NAME_3);
- final PersistableBundle appExtras1 = getPersistableBundle(
+ final PersistableBundle appExtras1 = createPersistableBundle(
PACKAGE_NAME_1, 1L, 0.01, true, "appString1");
- final PersistableBundle launcherExtras1 = getPersistableBundle(
+ final PersistableBundle appExtras2 = createPersistableBundle(
+ PACKAGE_NAME_2, 2L, 0.02, true, "appString2");
+
+ final PersistableBundle launcherExtras1 = createPersistableBundle(
PACKAGE_NAME_1, 10L, 0.1, false, "launcherString1");
+ final PersistableBundle launcherExtras2 = createPersistableBundle(
+ PACKAGE_NAME_2, 20L, 0.2, false, "launcherString2");
final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder()
.setIcon(0x11220001)
@@ -208,14 +244,23 @@ public class PackageManagerSettingsTests {
.setMessage("1st message")
.setNeutralButtonText(0x11220003)
.build();
+ final SuspendDialogInfo dialogInfo2 = new SuspendDialogInfo.Builder()
+ .setIcon(0x22220001)
+ .setTitle(0x22220002)
+ .setMessage("2nd message")
+ .setNeutralButtonText(0x22220003)
+ .build();
- ps1.setSuspended(true, "suspendingPackage1", dialogInfo1, appExtras1, launcherExtras1, 0);
+ ps1.addOrUpdateSuspension("suspendingPackage1", dialogInfo1, appExtras1, launcherExtras1,
+ 0);
+ ps1.addOrUpdateSuspension("suspendingPackage2", dialogInfo2, appExtras2, launcherExtras2,
+ 0);
settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1);
- ps2.setSuspended(true, "suspendingPackage2", null, null, null, 0);
+ ps2.addOrUpdateSuspension("suspendingPackage3", null, appExtras1, null, 0);
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
- ps3.setSuspended(false, "irrelevant", dialogInfo1, null, null, 0);
+ ps3.removeSuspension("irrelevant", 0);
settingsUnderTest.mPackages.put(PACKAGE_NAME_3, ps3);
settingsUnderTest.writePackageRestrictionsLPr(0);
@@ -229,27 +274,39 @@ public class PackageManagerSettingsTests {
final PackageUserState readPus1 = settingsUnderTest.mPackages.get(PACKAGE_NAME_1)
.readUserState(0);
assertThat(readPus1.suspended, is(true));
- assertThat(readPus1.suspendingPackage, equalTo("suspendingPackage1"));
- assertThat(readPus1.dialogInfo, equalTo(dialogInfo1));
- assertThat(BaseBundle.kindofEquals(readPus1.suspendedAppExtras, appExtras1), is(true));
- assertThat(BaseBundle.kindofEquals(readPus1.suspendedLauncherExtras, launcherExtras1),
+ assertThat(readPus1.suspendParams.size(), is(2));
+
+ assertThat(readPus1.suspendParams.keyAt(0), is("suspendingPackage1"));
+ final PackageUserState.SuspendParams params11 = readPus1.suspendParams.valueAt(0);
+ assertThat(params11, is(notNullValue()));
+ assertThat(params11.dialogInfo, is(dialogInfo1));
+ assertThat(BaseBundle.kindofEquals(params11.appExtras, appExtras1), is(true));
+ assertThat(BaseBundle.kindofEquals(params11.launcherExtras, launcherExtras1),
+ is(true));
+
+ assertThat(readPus1.suspendParams.keyAt(1), is("suspendingPackage2"));
+ final PackageUserState.SuspendParams params12 = readPus1.suspendParams.valueAt(1);
+ assertThat(params12, is(notNullValue()));
+ assertThat(params12.dialogInfo, is(dialogInfo2));
+ assertThat(BaseBundle.kindofEquals(params12.appExtras, appExtras2), is(true));
+ assertThat(BaseBundle.kindofEquals(params12.launcherExtras, launcherExtras2),
is(true));
final PackageUserState readPus2 = settingsUnderTest.mPackages.get(PACKAGE_NAME_2)
.readUserState(0);
assertThat(readPus2.suspended, is(true));
- assertThat(readPus2.suspendingPackage, equalTo("suspendingPackage2"));
- assertThat(readPus2.dialogInfo, is(nullValue()));
- assertThat(readPus2.suspendedAppExtras, is(nullValue()));
- assertThat(readPus2.suspendedLauncherExtras, is(nullValue()));
+ assertThat(readPus2.suspendParams.size(), is(1));
+ assertThat(readPus2.suspendParams.keyAt(0), is("suspendingPackage3"));
+ final PackageUserState.SuspendParams params21 = readPus2.suspendParams.valueAt(0);
+ assertThat(params21, is(notNullValue()));
+ assertThat(params21.dialogInfo, is(nullValue()));
+ assertThat(BaseBundle.kindofEquals(params21.appExtras, appExtras1), is(true));
+ assertThat(params21.launcherExtras, is(nullValue()));
final PackageUserState readPus3 = settingsUnderTest.mPackages.get(PACKAGE_NAME_3)
.readUserState(0);
assertThat(readPus3.suspended, is(false));
- assertThat(readPus3.suspendingPackage, is(nullValue()));
- assertThat(readPus3.dialogInfo, is(nullValue()));
- assertThat(readPus3.suspendedAppExtras, is(nullValue()));
- assertThat(readPus3.suspendedLauncherExtras, is(nullValue()));
+ assertThat(readPus3.suspendParams, is(nullValue()));
}
@Test
@@ -940,10 +997,10 @@ public class PackageManagerSettingsTests {
+ "</packages>").getBytes());
}
- private void writePackageRestrictions_oldSuspendInfoXml(final int userId) {
+ private void writePackageRestrictions_noSuspendingPackageXml(final int userId) {
writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/users/"
+ userId + "/package-restrictions.xml"),
- ( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<package-restrictions>\n"
+ " <pkg name=\"" + PACKAGE_NAME_1 + "\" suspended=\"true\" />"
+ " <pkg name=\"" + PACKAGE_NAME_2 + "\" suspended=\"false\" />"
@@ -955,6 +1012,30 @@ public class PackageManagerSettingsTests {
.getBytes());
}
+ private void writePackageRestrictions_noSuspendParamsMapXml(final int userId) {
+ writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/users/"
+ + userId + "/package-restrictions.xml"),
+ ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<package-restrictions>\n"
+ + " <pkg name=\"" + PACKAGE_NAME_1 + "\" "
+ + " suspended=\"true\" suspending-package=\"" + PACKAGE_NAME_3 + "\">\n"
+ + " <suspended-dialog-info dialogMessage=\"Dialog Message\""
+ + " iconResId=\"" + TEST_RESOURCE_ID + "\"/>\n"
+ + " <suspended-app-extras>\n"
+ + " <string name=\"app_extra_string\">value</string>\n"
+ + " </suspended-app-extras>\n"
+ + " <suspended-launcher-extras>\n"
+ + " <long name=\"launcher_extra_long\" value=\"4\" />\n"
+ + " </suspended-launcher-extras>\n"
+ + " </pkg>\n"
+ + " <preferred-activities />\n"
+ + " <persistent-preferred-activities />\n"
+ + " <crossProfile-intent-filters />\n"
+ + " <default-apps />\n"
+ + "</package-restrictions>\n")
+ .getBytes());
+ }
+
private void writeStoppedPackagesXml() {
writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages-stopped.xml"),
( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
index 8eaf35f6432f..fc5a0ba1af7b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
@@ -26,6 +26,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageUserState;
import android.content.pm.SuspendDialogInfo;
import android.os.PersistableBundle;
+import android.util.ArrayMap;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
@@ -175,18 +176,43 @@ public class PackageUserStateTest {
assertThat(testUserState03.equals(oldUserState), is(false));
}
+ private static PackageUserState.SuspendParams createSuspendParams(SuspendDialogInfo dialogInfo,
+ PersistableBundle appExtras, PersistableBundle launcherExtras) {
+ PackageUserState.SuspendParams obj = PackageUserState.SuspendParams.getInstanceOrNull(
+ dialogInfo, appExtras, launcherExtras);
+ return obj;
+ }
+
+ private static PersistableBundle createPersistableBundle(String lKey, long lValue, String sKey,
+ String sValue, String dKey, double dValue) {
+ final PersistableBundle result = new PersistableBundle(3);
+ if (lKey != null) {
+ result.putLong("com.unit_test." + lKey, lValue);
+ }
+ if (sKey != null) {
+ result.putString("com.unit_test." + sKey, sValue);
+ }
+ if (dKey != null) {
+ result.putDouble("com.unit_test." + dKey, dValue);
+ }
+ return result;
+ }
+
@Test
public void testPackageUserState05() {
- PersistableBundle appExtras1 = new PersistableBundle();
- PersistableBundle appExtras2 = new PersistableBundle();
- appExtras1.putInt("appExtraId", 1);
- appExtras2.putInt("appExtraId", 2);
- PersistableBundle launcherExtras1 = new PersistableBundle();
- PersistableBundle launcherExtras2 = new PersistableBundle();
- launcherExtras1.putString("name", "launcherExtras1");
- launcherExtras2.putString("name", "launcherExtras2");
+ final PersistableBundle appExtras1 = createPersistableBundle("appExtraId", 1, null, null,
+ null, 0);
+ final PersistableBundle appExtras2 = createPersistableBundle("appExtraId", 2, null, null,
+ null, 0);
+
+ final PersistableBundle launcherExtras1 = createPersistableBundle(null, 0, "name",
+ "launcherExtras1", null, 0);
+ final PersistableBundle launcherExtras2 = createPersistableBundle(null, 0, "name",
+ "launcherExtras2", null, 0);
+
final String suspendingPackage1 = "package1";
final String suspendingPackage2 = "package2";
+
final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder()
.setMessage("dialogMessage1")
.build();
@@ -194,38 +220,23 @@ public class PackageUserStateTest {
.setMessage("dialogMessage2")
.build();
+ final ArrayMap<String, PackageUserState.SuspendParams> paramsMap1 = new ArrayMap<>();
+ paramsMap1.put(suspendingPackage1, createSuspendParams(dialogInfo1, appExtras1,
+ launcherExtras1));
+ final ArrayMap<String, PackageUserState.SuspendParams> paramsMap2 = new ArrayMap<>();
+ paramsMap2.put(suspendingPackage2, createSuspendParams(dialogInfo2,
+ appExtras2, launcherExtras2));
+
+
final PackageUserState testUserState1 = new PackageUserState();
testUserState1.suspended = true;
- testUserState1.suspendedAppExtras = appExtras1;
- testUserState1.suspendedLauncherExtras = launcherExtras1;
- testUserState1.suspendingPackage = suspendingPackage1;
- testUserState1.dialogInfo = dialogInfo1;
+ testUserState1.suspendParams = paramsMap1;
PackageUserState testUserState2 = new PackageUserState(testUserState1);
assertThat(testUserState1.equals(testUserState2), is(true));
- testUserState2.suspendingPackage = suspendingPackage2;
- assertThat(testUserState1.equals(testUserState2), is(false));
-
- testUserState2 = new PackageUserState(testUserState1);
- testUserState2.suspendedAppExtras = appExtras2;
- assertThat(testUserState1.equals(testUserState2), is(false));
-
- testUserState2 = new PackageUserState(testUserState1);
- testUserState2.suspendedLauncherExtras = launcherExtras2;
- assertThat(testUserState1.equals(testUserState2), is(false));
-
- testUserState2 = new PackageUserState(testUserState1);
- testUserState2.dialogInfo = dialogInfo2;
+ testUserState2.suspendParams = paramsMap2;
+ // Should not be equal since suspendParams maps are different
assertThat(testUserState1.equals(testUserState2), is(false));
-
- testUserState2 = new PackageUserState(testUserState1);
- testUserState2.suspended = testUserState1.suspended = false;
- // Everything is different but irrelevant if suspended is false
- testUserState2.suspendingPackage = suspendingPackage2;
- testUserState2.dialogInfo = dialogInfo2;
- testUserState2.suspendedAppExtras = appExtras2;
- testUserState2.suspendedLauncherExtras = launcherExtras2;
- assertThat(testUserState1.equals(testUserState2), is(true));
}
@Test
@@ -243,4 +254,46 @@ public class PackageUserStateTest {
assertThat(userState1.equals(userState2), is(false));
}
+ @Test
+ public void testPackageUserState07() {
+ final PersistableBundle appExtras1 = createPersistableBundle("appExtraId", 1, null, null,
+ null, 0);
+ final PersistableBundle appExtras2 = createPersistableBundle("appExtraId", 2, null, null,
+ null, 0);
+
+ final PersistableBundle launcherExtras1 = createPersistableBundle(null, 0, "name",
+ "launcherExtras1", null, 0);
+ final PersistableBundle launcherExtras2 = createPersistableBundle(null, 0, "name",
+ "launcherExtras2", null, 0);
+
+ final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder()
+ .setMessage("dialogMessage1")
+ .build();
+ final SuspendDialogInfo dialogInfo2 = new SuspendDialogInfo.Builder()
+ .setMessage("dialogMessage2")
+ .build();
+
+ final PackageUserState.SuspendParams params1;
+ PackageUserState.SuspendParams params2;
+ params1 = createSuspendParams(dialogInfo1, appExtras1, launcherExtras1);
+ params2 = createSuspendParams(dialogInfo1, appExtras1, launcherExtras1);
+ // Everything is same
+ assertThat(params1.equals(params2), is(true));
+
+ params2 = createSuspendParams(dialogInfo2, appExtras1, launcherExtras1);
+ // DialogInfo is different
+ assertThat(params1.equals(params2), is(false));
+
+ params2 = createSuspendParams(dialogInfo1, appExtras2, launcherExtras1);
+ // app extras are different
+ assertThat(params1.equals(params2), is(false));
+
+ params2 = createSuspendParams(dialogInfo1, appExtras1, launcherExtras2);
+ // Launcher extras are different
+ assertThat(params1.equals(params2), is(false));
+
+ params2 = createSuspendParams(dialogInfo2, appExtras2, launcherExtras2);
+ // Everything is different
+ assertThat(params1.equals(params2), is(false));
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
index 350114c792bf..4165052fa675 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
@@ -175,8 +175,8 @@ public class ActivityStartInterceptorTest {
.build();
when(mPackageManagerInternal.getSuspendingPackage(TEST_PACKAGE_NAME, TEST_USER_ID))
.thenReturn(suspendingPackage);
- when(mPackageManagerInternal.getSuspendedDialogInfo(TEST_PACKAGE_NAME, TEST_USER_ID))
- .thenReturn(dialogInfo);
+ when(mPackageManagerInternal.getSuspendedDialogInfo(TEST_PACKAGE_NAME, suspendingPackage,
+ TEST_USER_ID)).thenReturn(dialogInfo);
// THEN calling intercept returns true
assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));