diff options
| author | 2016-04-14 17:19:16 -0700 | |
|---|---|---|
| committer | 2016-04-14 17:42:32 -0700 | |
| commit | 0033b2a190feeda8b41dd62b489aca3a19a09d5b (patch) | |
| tree | 8609444460f1aca8ba7d3df91c44a7c35369297a | |
| parent | 95a4791d1a0dfbd1898f010f0a2d1b1985a46079 (diff) | |
Remove all icon bitmaps when a publisher is uninstalled.
- Also show the directory sizes on dumpsys.
Bug 28196831
Change-Id: I3202fcd3151da3b26b436732e8103caf93aba525
3 files changed, 136 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index ac6510ae57ac..0ac5c1fef30c 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -907,6 +907,16 @@ public class ShortcutService extends IShortcutService.Stub { } } + public void cleanupBitmapsForPackage(@UserIdInt int userId, String packageName) { + final File packagePath = new File(getUserBitmapFilePath(userId), packageName); + if (!packagePath.isDirectory()) { + return; + } + if (!(FileUtils.deleteContents(packagePath) && packagePath.delete())) { + Slog.w(TAG, "Unable to remove directory " + packagePath); + } + } + @VisibleForTesting static class FileOutputStreamWithPath extends FileOutputStream { private final File mFile; @@ -1572,7 +1582,7 @@ public class ShortcutService extends IShortcutService.Stub { // First, remove the package from the package list (if the package is a publisher). if (packageUserId == owningUserId) { - if (mUser.removePackage(packageName) != null) { + if (mUser.removePackage(this, packageName) != null) { doNotify = true; } } @@ -2084,11 +2094,11 @@ public class ShortcutService extends IShortcutService.Stub { pw.println(mIconPersistFormat); pw.print(" Icon quality: "); pw.println(mIconPersistQuality); - pw.print(" saveDelayMillis:"); + pw.print(" saveDelayMillis: "); pw.println(mSaveDelayMillis); - pw.print(" resetInterval:"); + pw.print(" resetInterval: "); pw.println(mResetInterval); - pw.print(" maxUpdatesPerInterval:"); + pw.print(" maxUpdatesPerInterval: "); pw.println(mMaxUpdatesPerInterval); pw.print(" maxDynamicShortcuts:"); pw.println(mMaxDynamicShortcuts); @@ -2416,7 +2426,6 @@ public class ShortcutService extends IShortcutService.Stub { return mPackageManagerInternal; } - @VisibleForTesting File getUserBitmapFilePath(@UserIdInt int userId) { return new File(injectUserDataPath(userId), DIRECTORY_BITMAPS); } diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java index 593f607f6268..0b8c3a2ee8be 100644 --- a/services/core/java/com/android/server/pm/ShortcutUser.java +++ b/services/core/java/com/android/server/pm/ShortcutUser.java @@ -18,6 +18,7 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ComponentName; +import android.text.format.Formatter; import android.util.ArrayMap; import android.util.Slog; @@ -29,6 +30,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.function.Consumer; @@ -103,8 +105,12 @@ class ShortcutUser { return mPackages; } - public ShortcutPackage removePackage(@NonNull String packageName) { - return mPackages.remove(packageName); + public ShortcutPackage removePackage(@NonNull ShortcutService s, @NonNull String packageName) { + final ShortcutPackage removed = mPackages.remove(packageName); + + s.cleanupBitmapsForPackage(mUserId, packageName); + + return removed; } public ArrayMap<PackageWithUser, ShortcutLauncher> getAllLaunchers() { @@ -279,18 +285,51 @@ class ShortcutUser { pw.print(mUserId); pw.println(); + prefix += prefix + " "; + pw.print(prefix); - pw.print(" "); pw.print("Default launcher: "); pw.print(mLauncherComponent); pw.println(); for (int i = 0; i < mLaunchers.size(); i++) { - mLaunchers.valueAt(i).dump(s, pw, prefix + " "); + mLaunchers.valueAt(i).dump(s, pw, prefix); } for (int i = 0; i < mPackages.size(); i++) { - mPackages.valueAt(i).dump(s, pw, prefix + " "); + mPackages.valueAt(i).dump(s, pw, prefix); + } + + pw.println(); + pw.print(prefix); + pw.println("Bitmap directories: "); + dumpDirectorySize(s, pw, prefix + " ", s.getUserBitmapFilePath(mUserId)); + } + + private void dumpDirectorySize(@NonNull ShortcutService s, @NonNull PrintWriter pw, + @NonNull String prefix, File path) { + int numFiles = 0; + long size = 0; + final File[] children = path.listFiles(); + if (children != null) { + for (File child : path.listFiles()) { + if (child.isFile()) { + numFiles++; + size += child.length(); + } else if (child.isDirectory()) { + dumpDirectorySize(s, pw, prefix + " ", child); + } + } } + pw.print(prefix); + pw.print("Path: "); + pw.print(path.getName()); + pw.print("/ has "); + pw.print(numFiles); + pw.print(" files, size="); + pw.print(size); + pw.print(" ("); + pw.print(Formatter.formatFileSize(s.mContext, size)); + pw.println(")"); } } 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 ce02a79005ba..d20d5fa7f3b9 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java @@ -15,9 +15,36 @@ */ package com.android.server.pm; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamic; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamicOrPinned; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIcon; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIconFile; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIconResId; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIntents; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveTitle; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllKeyFieldsOnly; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotHaveIntents; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotHaveTitle; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotKeyFieldsOnly; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllPinned; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllUnique; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertBitmapSize; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertBundleEmpty; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackNotReceived; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackReceived; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicAndPinned; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicOnly; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertShortcutIds; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makeBundle; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.pfdToBitmap; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetAll; +import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set; + import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyList; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; @@ -27,7 +54,6 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.*; import android.annotation.NonNull; import android.annotation.Nullable; @@ -57,13 +83,11 @@ import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.graphics.drawable.Icon; import android.net.Uri; -import android.os.BaseBundle; import android.os.Bundle; import android.os.FileUtils; import android.os.Handler; import android.os.Looper; import android.os.Parcel; -import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.Process; import android.os.UserHandle; @@ -71,7 +95,6 @@ import android.os.UserManager; import android.test.InstrumentationTestCase; import android.test.mock.MockContext; import android.test.suitebuilder.annotation.SmallTest; -import android.util.ArraySet; import android.util.Log; import android.util.Pair; import android.util.SparseArray; @@ -84,9 +107,6 @@ import com.android.server.pm.LauncherAppsService.LauncherAppsImpl; import com.android.server.pm.ShortcutService.ConfigConstants; import com.android.server.pm.ShortcutService.FileOutputStreamWithPath; import com.android.server.pm.ShortcutUser.PackageWithUser; -import com.android.server.testutis.TestUtils; - -import libcore.io.IoUtils; import org.junit.Assert; import org.mockito.ArgumentCaptor; @@ -98,8 +118,6 @@ import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -4018,24 +4036,33 @@ public class ShortcutManagerTest extends InstrumentationTestCase { checkCanRestoreTo(false, spi2, 11, "x", "sig2x", "sig1", "y"); } + private boolean bitmapDirectoryExists(String packageName, int userId) { + final File path = new File(mService.getUserBitmapFilePath(userId), packageName); + return path.isDirectory(); + } + public void testHandlePackageDelete() { + final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource( + getTestContext().getResources(), R.drawable.black_32x32)); setCaller(CALLING_PACKAGE_1, USER_0); - assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1")))); + assertTrue(mManager.addDynamicShortcuts(list( + makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32) + ))); setCaller(CALLING_PACKAGE_2, USER_0); - assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1")))); + assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32)))); setCaller(CALLING_PACKAGE_3, USER_0); - assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1")))); + assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32)))); setCaller(CALLING_PACKAGE_1, USER_10); - assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1")))); + assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32)))); setCaller(CALLING_PACKAGE_2, USER_10); - assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1")))); + assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32)))); setCaller(CALLING_PACKAGE_3, USER_10); - assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1")))); + 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)); @@ -4044,6 +4071,13 @@ public class ShortcutManagerTest extends InstrumentationTestCase { 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)); + uninstallPackage(USER_0, CALLING_PACKAGE_1); mService.mPackageMonitor.onReceive(getTestContext(), genPackageDeleteIntent(CALLING_PACKAGE_1, USER_0)); @@ -4055,6 +4089,13 @@ public class ShortcutManagerTest extends InstrumentationTestCase { 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)); + uninstallPackage(USER_10, CALLING_PACKAGE_2); mService.mPackageMonitor.onReceive(getTestContext(), genPackageDeleteIntent(CALLING_PACKAGE_2, USER_10)); @@ -4066,6 +4107,13 @@ public class ShortcutManagerTest extends InstrumentationTestCase { 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)); + mInjectedPackages.remove(CALLING_PACKAGE_1); mInjectedPackages.remove(CALLING_PACKAGE_3); @@ -4078,6 +4126,13 @@ public class ShortcutManagerTest extends InstrumentationTestCase { 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)); + assertFalse(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)); + mService.handleUnlockUser(USER_10); assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0)); @@ -4086,6 +4141,13 @@ public class ShortcutManagerTest extends InstrumentationTestCase { assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10)); assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10)); assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10)); + + assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0)); + assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0)); + assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0)); + assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10)); + assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10)); + assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10)); } private void backupAndRestore() { |