summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/content/PackageMonitor.java10
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java53
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java79
3 files changed, 116 insertions, 26 deletions
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 7bd64e504c3d..c6b6a7fb999f 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -45,6 +45,7 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
sPackageFilt.addAction(Intent.ACTION_PACKAGE_CHANGED);
sPackageFilt.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
sPackageFilt.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+ sPackageFilt.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
sPackageFilt.addDataScheme("package");
sNonDataFilt.addAction(Intent.ACTION_UID_REMOVED);
sNonDataFilt.addAction(Intent.ACTION_USER_STOPPED);
@@ -275,6 +276,9 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
public void onFinishPackageChanges() {
}
+ public void onPackageDataCleared(String packageName, int uid) {
+ }
+
public int getChangingUserId() {
return mChangeUserId;
}
@@ -365,6 +369,12 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
}
onPackageModified(pkg);
}
+ } else if (Intent.ACTION_PACKAGE_DATA_CLEARED.equals(action)) {
+ String pkg = getPackageName(intent);
+ int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
+ if (pkg != null) {
+ onPackageDataCleared(pkg, uid);
+ }
} else if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
mDisappearingPackages = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
mChangeType = PACKAGE_TEMPORARY_CHANGE;
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 57641614cda8..c0874efe211c 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1561,48 +1561,46 @@ public class ShortcutService extends IShortcutService.Stub {
// === House keeping ===
- @VisibleForTesting
- void cleanUpPackageLocked(String packageName, int owningUserId, int packageUserId) {
- cleanUpPackageLocked(packageName, owningUserId, packageUserId,
- /* forceForCommandLine= */ false);
+ private void cleanUpPackageForAllLoadedUsers(String packageName, @UserIdInt int packageUserId) {
+ synchronized (mLock) {
+ forEachLoadedUserLocked(user ->
+ cleanUpPackageLocked(packageName, user.getUserId(), packageUserId));
+ }
}
/**
* Remove all the information associated with a package. This will really remove all the
* information, including the restore information (i.e. it'll remove packages even if they're
* shadow).
+ *
+ * This is called when an app is uninstalled, or an app gets "clear data"ed.
*/
- private void cleanUpPackageLocked(String packageName, int owningUserId, int packageUserId,
- boolean forceForCommandLine) {
- if (!forceForCommandLine && isPackageInstalled(packageName, packageUserId)) {
- wtf("Package " + packageName + " is still installed for user " + packageUserId);
- return;
- }
-
+ @VisibleForTesting
+ void cleanUpPackageLocked(String packageName, int owningUserId, int packageUserId) {
final boolean wasUserLoaded = isUserLoadedLocked(owningUserId);
- final ShortcutUser mUser = getUserShortcutsLocked(owningUserId);
+ final ShortcutUser user = getUserShortcutsLocked(owningUserId);
boolean doNotify = false;
// First, remove the package from the package list (if the package is a publisher).
if (packageUserId == owningUserId) {
- if (mUser.removePackage(this, packageName) != null) {
+ if (user.removePackage(this, packageName) != null) {
doNotify = true;
}
}
// Also remove from the launcher list (if the package is a launcher).
- mUser.removeLauncher(packageUserId, packageName);
+ user.removeLauncher(packageUserId, packageName);
// Then remove pinned shortcuts from all launchers.
- final ArrayMap<PackageWithUser, ShortcutLauncher> launchers = mUser.getAllLaunchers();
+ final ArrayMap<PackageWithUser, ShortcutLauncher> launchers = user.getAllLaunchers();
for (int i = launchers.size() - 1; i >= 0; i--) {
launchers.valueAt(i).cleanUpPackage(packageName, packageUserId);
}
// Now there may be orphan shortcuts because we removed pinned shortucts at the previous
// step. Remove them too.
- for (int i = mUser.getAllPackages().size() - 1; i >= 0; i--) {
- mUser.getAllPackages().valueAt(i).refreshPinnedFlags(this);
+ for (int i = user.getAllPackages().size() - 1; i >= 0; i--) {
+ user.getAllPackages().valueAt(i).refreshPinnedFlags(this);
}
scheduleSaveUser(owningUserId);
@@ -1842,6 +1840,11 @@ public class ShortcutService extends IShortcutService.Stub {
public void onPackageRemoved(String packageName, int uid) {
handlePackageRemoved(packageName, getChangingUserId());
}
+
+ @Override
+ public void onPackageDataCleared(String packageName, int uid) {
+ handlePackageDataCleared(packageName, getChangingUserId());
+ }
};
/**
@@ -1915,16 +1918,15 @@ public class ShortcutService extends IShortcutService.Stub {
Slog.d(TAG, String.format("handlePackageRemoved: %s user=%d", packageName,
packageUserId));
}
- handlePackageRemovedInner(packageName, packageUserId, /* forceForCommandLine =*/ false);
+ cleanUpPackageForAllLoadedUsers(packageName, packageUserId);
}
- private void handlePackageRemovedInner(String packageName, @UserIdInt int packageUserId,
- boolean forceForCommandLine) {
- synchronized (mLock) {
- forEachLoadedUserLocked(user ->
- cleanUpPackageLocked(packageName, user.getUserId(), packageUserId,
- forceForCommandLine));
+ private void handlePackageDataCleared(String packageName, int packageUserId) {
+ if (DEBUG) {
+ Slog.d(TAG, String.format("handlePackageDataCleared: %s user=%d", packageName,
+ packageUserId));
}
+ cleanUpPackageForAllLoadedUsers(packageName, packageUserId);
}
// === PackageManager interaction ===
@@ -2390,8 +2392,7 @@ public class ShortcutService extends IShortcutService.Stub {
Slog.i(TAG, "cmd: handleClearShortcuts: " + mUserId + ", " + packageName);
- ShortcutService.this.handlePackageRemovedInner(packageName, mUserId,
- /* forceForCommandLine= */ true);
+ ShortcutService.this.cleanUpPackageForAllLoadedUsers(packageName, mUserId);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
index bc43576c7caf..13518b555c76 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
@@ -1061,6 +1061,12 @@ public class ShortcutManagerTest extends InstrumentationTestCase {
i.putExtra(Intent.EXTRA_REPLACING, true);
return i;
}
+ private Intent genPackageDataClear(String packageName, int userId) {
+ Intent i = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED);
+ i.setData(Uri.parse("package:" + packageName));
+ i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ return i;
+ }
private ShortcutInfo parceled(ShortcutInfo si) {
Parcel p = Parcel.obtain();
@@ -4159,6 +4165,79 @@ public class ShortcutManagerTest extends InstrumentationTestCase {
assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
}
+ /** Almost ame as testHandlePackageDelete, except it doesn't uninstall packages. */
+ public void testHandlePackageClearData() {
+ final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+ getTestContext().getResources(), R.drawable.black_32x32));
+ setCaller(CALLING_PACKAGE_1, USER_0);
+ assertTrue(mManager.addDynamicShortcuts(list(
+ makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32)
+ )));
+
+ setCaller(CALLING_PACKAGE_2, USER_0);
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
+
+ setCaller(CALLING_PACKAGE_3, USER_0);
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
+
+ setCaller(CALLING_PACKAGE_1, USER_10);
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
+
+ setCaller(CALLING_PACKAGE_2, USER_10);
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
+
+ setCaller(CALLING_PACKAGE_3, USER_10);
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
+
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageDataClear(CALLING_PACKAGE_1, USER_0));
+
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageDataClear(CALLING_PACKAGE_2, USER_10));
+
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ }
+
public void testHandlePackageUpdate() throws Throwable {
// Set up shortcuts and launchers.