13145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki/* 23145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Copyright (C) 2016 The Android Open Source Project 33145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * 43145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 53145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * you may not use this file except in compliance with the License. 63145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * You may obtain a copy of the License at 73145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * 83145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 93145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * 103145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Unless required by applicable law or agreed to in writing, software 113145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 123145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * See the License for the specific language governing permissions and 143145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * limitations under the License. 153145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki */ 163145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukipackage com.android.server.pm; 173145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 183145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport android.annotation.NonNull; 193145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport android.annotation.UserIdInt; 203145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport android.content.pm.ShortcutInfo; 213145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport android.util.ArrayMap; 223145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport android.util.ArraySet; 232e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onukiimport android.util.Slog; 242e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 252e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onukiimport com.android.internal.annotations.VisibleForTesting; 262e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onukiimport com.android.server.pm.ShortcutUser.PackageWithUser; 273145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 283145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport org.xmlpull.v1.XmlPullParser; 293145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport org.xmlpull.v1.XmlPullParserException; 303145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport org.xmlpull.v1.XmlSerializer; 313145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 323145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport java.io.IOException; 333145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport java.io.PrintWriter; 342e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onukiimport java.util.ArrayList; 353145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport java.util.List; 363145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 373145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki/** 383145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Launcher information used by {@link ShortcutService}. 393145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki */ 409da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onukiclass ShortcutLauncher extends ShortcutPackageItem { 413145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki private static final String TAG = ShortcutService.TAG; 423145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 433145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki static final String TAG_ROOT = "launcher-pins"; 443145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 453145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki private static final String TAG_PACKAGE = "package"; 463145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki private static final String TAG_PIN = "pin"; 473145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 48d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki private static final String ATTR_LAUNCHER_USER_ID = "launcher-user"; 493145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki private static final String ATTR_VALUE = "value"; 503145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki private static final String ATTR_PACKAGE_NAME = "package-name"; 512e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki private static final String ATTR_PACKAGE_USER_ID = "package-user"; 523145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 539da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki private final int mOwnerUserId; 54d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki 553145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki /** 563145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Package name -> IDs. 573145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki */ 582e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki final private ArrayMap<PackageWithUser, ArraySet<String>> mPinnedShortcuts = new ArrayMap<>(); 593145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 604d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki private ShortcutLauncher(@NonNull ShortcutUser shortcutUser, 614d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki @UserIdInt int ownerUserId, @NonNull String packageName, 629da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki @UserIdInt int launcherUserId, ShortcutPackageInfo spi) { 634d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki super(shortcutUser, launcherUserId, packageName, 644d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki spi != null ? spi : ShortcutPackageInfo.newEmpty()); 659da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki mOwnerUserId = ownerUserId; 663145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 673145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 684d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki public ShortcutLauncher(@NonNull ShortcutUser shortcutUser, 694d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki @UserIdInt int ownerUserId, @NonNull String packageName, 709da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki @UserIdInt int launcherUserId) { 714d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki this(shortcutUser, ownerUserId, packageName, launcherUserId, null); 720acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki } 730acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki 749da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki @Override 759da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki public int getOwnerUserId() { 769da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki return mOwnerUserId; 77d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki } 78d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki 792e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki /** 802e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki * Called when the new package can't receive the backup, due to signature or version mismatch. 812e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki */ 822e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki @Override 832e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki protected void onRestoreBlocked(ShortcutService s) { 842e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki final ArrayList<PackageWithUser> pinnedPackages = 852e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki new ArrayList<>(mPinnedShortcuts.keySet()); 862e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki mPinnedShortcuts.clear(); 872e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki for (int i = pinnedPackages.size() - 1; i >= 0; i--) { 882e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki final PackageWithUser pu = pinnedPackages.get(i); 892e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki s.getPackageShortcutsLocked(pu.packageName, pu.userId) 902e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki .refreshPinnedFlags(s); 912e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 922e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 932e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 942e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki @Override 952e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki protected void onRestored(ShortcutService s) { 962e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki // Nothing to do. 972e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 982e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 999da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki public void pinShortcuts(@NonNull ShortcutService s, @UserIdInt int packageUserId, 1009da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki @NonNull String packageName, @NonNull List<String> ids) { 1019da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki final ShortcutPackage packageShortcuts = 1029da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki s.getPackageShortcutsLocked(packageName, packageUserId); 1030acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki 1042e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki final PackageWithUser pu = PackageWithUser.of(packageUserId, packageName); 1052e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 1063145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final int idSize = ids.size(); 1073145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki if (idSize == 0) { 1082e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki mPinnedShortcuts.remove(pu); 1093145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } else { 1102e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki final ArraySet<String> prevSet = mPinnedShortcuts.get(pu); 1113145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1123145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki // Pin shortcuts. Make sure only pin the ones that were visible to the caller. 1133145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki // i.e. a non-dynamic, pinned shortcut by *other launchers* shouldn't be pinned here. 1143145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1153145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final ArraySet<String> newSet = new ArraySet<>(); 1163145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1173145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki for (int i = 0; i < idSize; i++) { 1183145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final String id = ids.get(i); 1193145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final ShortcutInfo si = packageShortcuts.findShortcutById(id); 1203145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki if (si == null) { 1213145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki continue; 1223145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1233145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki if (si.isDynamic() || (prevSet != null && prevSet.contains(id))) { 1243145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki newSet.add(id); 1253145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1263145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1272e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki mPinnedShortcuts.put(pu, newSet); 1283145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1299da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki packageShortcuts.refreshPinnedFlags(s); 1303145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1313145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1323145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki /** 1333145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Return the pinned shortcut IDs for the publisher package. 1343145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki */ 1352e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki public ArraySet<String> getPinnedShortcutIds(@NonNull String packageName, 1362e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki @UserIdInt int packageUserId) { 1372e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki return mPinnedShortcuts.get(PackageWithUser.of(packageUserId, packageName)); 1383145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1393145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1402e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki boolean cleanUpPackage(String packageName, @UserIdInt int packageUserId) { 1412e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki return mPinnedShortcuts.remove(PackageWithUser.of(packageUserId, packageName)) != null; 1423145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1433145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1443145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki /** 1453145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Persist. 1463145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki */ 1479da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki @Override 1489da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki public void saveToXml(XmlSerializer out, boolean forBackup) 1499da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki throws IOException { 1503145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final int size = mPinnedShortcuts.size(); 1513145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki if (size == 0) { 1523145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki return; // Nothing to write. 1533145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1543145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1553145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki out.startTag(null, TAG_ROOT); 1569da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME, getPackageName()); 1579da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki ShortcutService.writeAttr(out, ATTR_LAUNCHER_USER_ID, getPackageUserId()); 1589da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki getPackageInfo().saveToXml(out); 1593145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1603145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki for (int i = 0; i < size; i++) { 1612e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki final PackageWithUser pu = mPinnedShortcuts.keyAt(i); 1622e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 1632e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki if (forBackup && (pu.userId != getOwnerUserId())) { 1642e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki continue; // Target package on a different user, skip. (i.e. work profile) 1652e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 1662e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 1673145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki out.startTag(null, TAG_PACKAGE); 1682e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME, pu.packageName); 1692e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki ShortcutService.writeAttr(out, ATTR_PACKAGE_USER_ID, pu.userId); 1703145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1713145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final ArraySet<String> ids = mPinnedShortcuts.valueAt(i); 1723145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final int idSize = ids.size(); 1733145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki for (int j = 0; j < idSize; j++) { 1743145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki ShortcutService.writeTagValue(out, TAG_PIN, ids.valueAt(j)); 1753145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1763145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki out.endTag(null, TAG_PACKAGE); 1773145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1783145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1793145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki out.endTag(null, TAG_ROOT); 1803145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 1813145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1823145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki /** 1833145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Load. 1843145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki */ 1854d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki public static ShortcutLauncher loadFromXml(XmlPullParser parser, ShortcutUser shortcutUser, 1864d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki int ownerUserId, boolean fromBackup) throws IOException, XmlPullParserException { 1873145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final String launcherPackageName = ShortcutService.parseStringAttribute(parser, 1883145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki ATTR_PACKAGE_NAME); 1899da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 1909da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki // If restoring, just use the real user ID. 1919da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki final int launcherUserId = 1929da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki fromBackup ? ownerUserId 1939da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki : ShortcutService.parseIntAttribute(parser, ATTR_LAUNCHER_USER_ID, ownerUserId); 1943145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1954d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki final ShortcutLauncher ret = new ShortcutLauncher(shortcutUser, launcherUserId, 1964d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki launcherPackageName, launcherUserId); 1973145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 1983145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki ArraySet<String> ids = null; 1993145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final int outerDepth = parser.getDepth(); 2003145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki int type; 2013145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 2023145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2033145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki if (type != XmlPullParser.START_TAG) { 2043145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki continue; 2053145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 2063145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final int depth = parser.getDepth(); 2073145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final String tag = parser.getName(); 2089da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki if (depth == outerDepth + 1) { 2099da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki switch (tag) { 2109da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki case ShortcutPackageInfo.TAG_ROOT: 2112e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki ret.getPackageInfo().loadFromXml(parser, fromBackup); 2129da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki continue; 2139da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki case TAG_PACKAGE: { 2149da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki final String packageName = ShortcutService.parseStringAttribute(parser, 2159da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki ATTR_PACKAGE_NAME); 2162e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki final int packageUserId = fromBackup ? ownerUserId 2172e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki : ShortcutService.parseIntAttribute(parser, 2182e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki ATTR_PACKAGE_USER_ID, ownerUserId); 2199da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki ids = new ArraySet<>(); 2202e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki ret.mPinnedShortcuts.put( 2212e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki PackageWithUser.of(packageUserId, packageName), ids); 2229da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki continue; 2239da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 2243145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 2259da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 2269da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki if (depth == outerDepth + 2) { 2279da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki switch (tag) { 2289da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki case TAG_PIN: { 2292e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki if (ids == null) { 2302e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki Slog.w(TAG, TAG_PIN + " in invalid place"); 2312e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } else { 2322e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki ids.add(ShortcutService.parseStringAttribute(parser, ATTR_VALUE)); 2332e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 2349da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki continue; 2359da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 2363145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 2373145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 2389da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki ShortcutService.warnForInvalidTag(depth, tag); 2399da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 2403145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki return ret; 2413145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 2423145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 2433145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki public void dump(@NonNull ShortcutService s, @NonNull PrintWriter pw, @NonNull String prefix) { 2443145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.println(); 2453145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 2463145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.print(prefix); 2473145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.print("Launcher: "); 2489da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki pw.print(getPackageName()); 2499da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki pw.print(" Package user: "); 2509da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki pw.print(getPackageUserId()); 2512e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki pw.print(" Owner user: "); 2522e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki pw.print(getOwnerUserId()); 2539da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki pw.println(); 2549da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 2559da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki getPackageInfo().dump(s, pw, prefix + " "); 2563145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.println(); 2573145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 2583145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final int size = mPinnedShortcuts.size(); 2593145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki for (int i = 0; i < size; i++) { 2603145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.println(); 2613145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 2622e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki final PackageWithUser pu = mPinnedShortcuts.keyAt(i); 2632e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 2643145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.print(prefix); 2653145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.print(" "); 2663145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.print("Package: "); 2672e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki pw.print(pu.packageName); 2682e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki pw.print(" User: "); 2692e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki pw.println(pu.userId); 2703145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 2713145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final ArraySet<String> ids = mPinnedShortcuts.valueAt(i); 2723145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki final int idSize = ids.size(); 2733145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki 2743145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki for (int j = 0; j < idSize; j++) { 2753145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.print(prefix); 2760acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki pw.print(" Pinned: "); 2773145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.print(ids.valueAt(j)); 2783145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki pw.println(); 2793145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 2803145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 2813145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki } 2822e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 2832e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki @VisibleForTesting 2842e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki ArraySet<String> getAllPinnedShortcutsForTest(String packageName, int packageUserId) { 2852e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki return new ArraySet<>(mPinnedShortcuts.get(PackageWithUser.of(packageUserId, packageName))); 2862e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 2873145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki} 288