From 3f4b1ca97ad7c31bdbe2ba29264841fb58683e81 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Fri, 11 Mar 2016 13:44:32 -0800 Subject: [PATCH] ShortcutManager refactor: per-user information class Bug 27548047 Change-Id: Id6de8bfbad6281daec5e89be85ba8b140b599268 --- .../android/server/pm/ShortcutService.java | 164 ++++++++++-------- 1 file changed, 91 insertions(+), 73 deletions(-) diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 1cd0592db2676..0b0f7abbce4e1 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -88,6 +88,7 @@ import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.function.Predicate; /** @@ -149,6 +150,7 @@ public class ShortcutService extends IShortcutService.Stub { static final String DIRECTORY_BITMAPS = "bitmaps"; static final String TAG_ROOT = "root"; + static final String TAG_USER = "user"; static final String TAG_PACKAGE = "package"; static final String TAG_LAST_RESET_TIME = "last_reset_time"; static final String TAG_INTENT_EXTRAS = "intent-extras"; @@ -221,11 +223,10 @@ public class ShortcutService extends IShortcutService.Stub { private long mRawLastResetTime; /** - * User ID -> package name -> list of ShortcutInfos. + * User ID -> UserShortcuts */ @GuardedBy("mLock") - private final SparseArray> mShortcuts = - new SparseArray<>(); + private final SparseArray mUsers = new SparseArray<>(); /** * Max number of dynamic shortcuts that each application can have at a time. @@ -313,7 +314,7 @@ public class ShortcutService extends IShortcutService.Stub { /** lifecycle event */ void onCleanupUserInner(int userId) { // Unload - mShortcuts.delete(userId); + mUsers.delete(userId); } /** Return the base state file name */ @@ -583,20 +584,9 @@ public class ShortcutService extends IShortcutService.Stub { XmlSerializer out = new FastXmlSerializer(); out.setOutput(outs, StandardCharsets.UTF_8.name()); out.startDocument(null, true); - out.startTag(null, TAG_ROOT); - final ArrayMap packages = getUserShortcutsLocked(userId); + getUserShortcutsLocked(userId).saveToXml(out); - // Body. - for (int i = 0; i < packages.size(); i++) { - final String packageName = packages.keyAt(i); - final PackageShortcuts packageShortcuts = packages.valueAt(i); - - packageShortcuts.saveToXml(out); - } - - // Epilogue. - out.endTag(null, TAG_ROOT); out.endDocument(); // Close. @@ -612,7 +602,7 @@ public class ShortcutService extends IShortcutService.Stub { } @Nullable - private ArrayMap loadUserLocked(@UserIdInt int userId) { + private UserShortcuts loadUserLocked(@UserIdInt int userId) { final File path = new File(injectUserDataPath(userId), FILENAME_USER_PACKAGES); if (DEBUG) { Slog.i(TAG, "Loading from " + path); @@ -628,13 +618,11 @@ public class ShortcutService extends IShortcutService.Stub { } return null; } - final ArrayMap ret = new ArrayMap<>(); + UserShortcuts ret = null; try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(in, StandardCharsets.UTF_8.name()); - PackageShortcuts shortcuts = null; - int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { @@ -647,22 +635,9 @@ public class ShortcutService extends IShortcutService.Stub { Slog.d(TAG, String.format("depth=%d type=%d name=%s", depth, type, tag)); } - switch (depth) { - case 1: { - if (TAG_ROOT.equals(tag)) { - continue; - } - break; - } - case 2: { - switch (tag) { - case TAG_PACKAGE: - shortcuts = PackageShortcuts.loadFromXml(parser, userId); - ret.put(shortcuts.mPackageName, shortcuts); - continue; - } - break; - } + if ((depth == 1) && TAG_USER.equals(tag)) { + ret = UserShortcuts.loadFromXml(parser, userId); + continue; } throwForInvalidTag(depth, tag); } @@ -731,14 +706,14 @@ public class ShortcutService extends IShortcutService.Stub { /** Return the per-user state. */ @GuardedBy("mLock") @NonNull - private ArrayMap getUserShortcutsLocked(@UserIdInt int userId) { - ArrayMap userPackages = mShortcuts.get(userId); + private UserShortcuts getUserShortcutsLocked(@UserIdInt int userId) { + UserShortcuts userPackages = mUsers.get(userId); if (userPackages == null) { userPackages = loadUserLocked(userId); if (userPackages == null) { - userPackages = new ArrayMap<>(); + userPackages = new UserShortcuts(userId); } - mShortcuts.put(userId, userPackages); + mUsers.put(userId, userPackages); } return userPackages; } @@ -748,11 +723,11 @@ public class ShortcutService extends IShortcutService.Stub { @NonNull private PackageShortcuts getPackageShortcutsLocked( @NonNull String packageName, @UserIdInt int userId) { - final ArrayMap userPackages = getUserShortcutsLocked(userId); - PackageShortcuts shortcuts = userPackages.get(packageName); + final UserShortcuts userPackages = getUserShortcutsLocked(userId); + PackageShortcuts shortcuts = userPackages.getPackages().get(packageName); if (shortcuts == null) { shortcuts = new PackageShortcuts(userId, packageName); - userPackages.put(packageName, shortcuts); + userPackages.getPackages().put(packageName, shortcuts); } return shortcuts; } @@ -1335,7 +1310,7 @@ public class ShortcutService extends IShortcutService.Stub { userId, ret, cloneFlag); } else { final ArrayMap packages = - getUserShortcutsLocked(userId); + getUserShortcutsLocked(userId).getPackages(); for (int i = packages.size() - 1; i >= 0; i--) { getShortcutsInnerLocked( packages.keyAt(i), @@ -1512,38 +1487,14 @@ public class ShortcutService extends IShortcutService.Stub { pw.print(mIconPersistQuality); pw.println(); - pw.println(); - for (int i = 0; i < mShortcuts.size(); i++) { - dumpUserLocked(pw, mShortcuts.keyAt(i)); + for (int i = 0; i < mUsers.size(); i++) { + pw.println(); + mUsers.valueAt(i).dump(this, pw, " "); } } } - private void dumpUserLocked(PrintWriter pw, int userId) { - pw.print(" User: "); - pw.print(userId); - pw.println(); - - final ArrayMap packages = mShortcuts.get(userId); - if (packages == null) { - return; - } - for (int j = 0; j < packages.size(); j++) { - dumpPackageLocked(pw, userId, packages.keyAt(j)); - } - pw.println(); - } - - private void dumpPackageLocked(PrintWriter pw, int userId, String packageName) { - final PackageShortcuts packageShortcuts = mShortcuts.get(userId).get(packageName); - if (packageShortcuts == null) { - return; - } - - packageShortcuts.dump(this, pw, " "); - } - static String formatTime(long time) { Time tobj = new Time(); tobj.set(time); @@ -1694,8 +1645,8 @@ public class ShortcutService extends IShortcutService.Stub { } @VisibleForTesting - SparseArray> getShortcutsForTest() { - return mShortcuts; + SparseArray getShortcutsForTest() { + return mUsers; } @VisibleForTesting @@ -1736,6 +1687,73 @@ public class ShortcutService extends IShortcutService.Stub { } } +class UserShortcuts { + private static final String TAG = ShortcutService.TAG; + + @UserIdInt + final int mUserId; + + private final ArrayMap mPackages = new ArrayMap<>(); + + public UserShortcuts(int userId) { + mUserId = userId; + } + + public ArrayMap getPackages() { + return mPackages; + } + + public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException { + out.startTag(null, ShortcutService.TAG_USER); + + for (int i = 0; i < mPackages.size(); i++) { + final String packageName = mPackages.keyAt(i); + final PackageShortcuts packageShortcuts = mPackages.valueAt(i); + + packageShortcuts.saveToXml(out); + } + + out.endTag(null, ShortcutService.TAG_USER); + } + + public static UserShortcuts loadFromXml(XmlPullParser parser, int userId) + throws IOException, XmlPullParserException { + final UserShortcuts ret = new UserShortcuts(userId); + + final int outerDepth = parser.getDepth(); + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type != XmlPullParser.START_TAG) { + continue; + } + final int depth = parser.getDepth(); + final String tag = parser.getName(); + switch (tag) { + case ShortcutService.TAG_PACKAGE: + final PackageShortcuts shortcuts = PackageShortcuts.loadFromXml(parser, userId); + + // Don't use addShortcut(), we don't need to save the icon. + ret.getPackages().put(shortcuts.mPackageName, shortcuts); + continue; + } + throw ShortcutService.throwForInvalidTag(depth, tag); + } + return ret; + } + + public void dump(@NonNull ShortcutService s, @NonNull PrintWriter pw, @NonNull String prefix) { + pw.print(" "); + pw.print("User: "); + pw.print(mUserId); + pw.println(); + + for (int i = 0; i < mPackages.size(); i++) { + mPackages.valueAt(i).dump(s, pw, prefix + " "); + } + } +} + /** * All the information relevant to shortcuts from a single package (per-user). */