ShortcutLauncher.java revision d99c6f04bbb68f8be78f2c3ca625a3a8d5645275
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;
233145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
243145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport org.xmlpull.v1.XmlPullParser;
253145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport org.xmlpull.v1.XmlPullParserException;
263145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport org.xmlpull.v1.XmlSerializer;
273145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
283145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport java.io.IOException;
293145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport java.io.PrintWriter;
303145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onukiimport java.util.List;
313145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
323145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki/**
333145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki * Launcher information used by {@link ShortcutService}.
343145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki */
350acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onukiclass ShortcutLauncher implements ShortcutPackageItem {
363145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    private static final String TAG = ShortcutService.TAG;
373145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
383145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    static final String TAG_ROOT = "launcher-pins";
393145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
403145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    private static final String TAG_PACKAGE = "package";
413145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    private static final String TAG_PIN = "pin";
423145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
43d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki    private static final String ATTR_LAUNCHER_USER_ID = "launcher-user";
443145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    private static final String ATTR_VALUE = "value";
453145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    private static final String ATTR_PACKAGE_NAME = "package-name";
463145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
473145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    @UserIdInt
480acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    private final int mUserId;
493145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
503145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    @NonNull
510acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    private final String mPackageName;
523145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
53d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki    @UserIdInt
54d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki    private final int mLauncherUserId;
55d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki
563145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    /**
573145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki     * Package name -> IDs.
583145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki     */
593145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    final private ArrayMap<String, ArraySet<String>> mPinnedShortcuts = new ArrayMap<>();
603145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
61d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki    ShortcutLauncher(@UserIdInt int userId, @NonNull String packageName,
62d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki            @UserIdInt int launcherUserId) {
633145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        mUserId = userId;
643145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        mPackageName = packageName;
65d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki        mLauncherUserId = launcherUserId;
663145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    }
673145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
680acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    @UserIdInt
690acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    public int getUserId() {
700acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki        return mUserId;
710acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    }
720acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki
73d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki    @UserIdInt
74d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki    public int getLauncherUserId() {
75d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki        return mLauncherUserId;
76d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki    }
77d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki
780acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    @NonNull
790acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    public String getPackageName() {
800acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki        return mPackageName;
810acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    }
820acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki
833145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    public void pinShortcuts(@NonNull ShortcutService s, @NonNull String packageName,
843145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            @NonNull List<String> ids) {
853145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        final int idSize = ids.size();
863145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        if (idSize == 0) {
873145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            mPinnedShortcuts.remove(packageName);
883145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        } else {
893145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final ArraySet<String> prevSet = mPinnedShortcuts.get(packageName);
903145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
913145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            // Pin shortcuts.  Make sure only pin the ones that were visible to the caller.
923145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            // i.e. a non-dynamic, pinned shortcut by *other launchers* shouldn't be pinned here.
933145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
943145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final ShortcutPackage packageShortcuts =
953145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    s.getPackageShortcutsLocked(packageName, mUserId);
963145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final ArraySet<String> newSet = new ArraySet<>();
973145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
983145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            for (int i = 0; i < idSize; i++) {
993145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                final String id = ids.get(i);
1003145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                final ShortcutInfo si = packageShortcuts.findShortcutById(id);
1013145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                if (si == null) {
1023145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    continue;
1033145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                }
1043145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                if (si.isDynamic() || (prevSet != null && prevSet.contains(id))) {
1053145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    newSet.add(id);
1063145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                }
1073145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            }
1083145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            mPinnedShortcuts.put(packageName, newSet);
1093145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        }
1103145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        s.getPackageShortcutsLocked(packageName, mUserId).refreshPinnedFlags(s);
1113145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    }
1123145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1133145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    /**
1143145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki     * Return the pinned shortcut IDs for the publisher package.
1153145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki     */
1163145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    public ArraySet<String> getPinnedShortcutIds(@NonNull String packageName) {
1173145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        return mPinnedShortcuts.get(packageName);
1183145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    }
1193145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1203145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    boolean cleanUpPackage(String packageName) {
1213145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        return mPinnedShortcuts.remove(packageName) != null;
1223145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    }
1233145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1243145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    /**
1253145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki     * Persist.
1263145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki     */
1270acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki    public void saveToXml(XmlSerializer out, boolean forBackup) throws IOException {
1283145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        final int size = mPinnedShortcuts.size();
1293145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        if (size == 0) {
1303145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            return; // Nothing to write.
1313145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        }
1323145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1333145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        out.startTag(null, TAG_ROOT);
134d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki        ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME, mPackageName);
135d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki        ShortcutService.writeAttr(out, ATTR_LAUNCHER_USER_ID, mLauncherUserId);
1363145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1373145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        for (int i = 0; i < size; i++) {
1383145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            out.startTag(null, TAG_PACKAGE);
1393145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME,
1403145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    mPinnedShortcuts.keyAt(i));
1413145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1423145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final ArraySet<String> ids = mPinnedShortcuts.valueAt(i);
1433145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final int idSize = ids.size();
1443145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            for (int j = 0; j < idSize; j++) {
1453145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                ShortcutService.writeTagValue(out, TAG_PIN, ids.valueAt(j));
1463145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            }
1473145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            out.endTag(null, TAG_PACKAGE);
1483145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        }
1493145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1503145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        out.endTag(null, TAG_ROOT);
1513145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    }
1523145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1533145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    /**
1543145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki     * Load.
1553145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki     */
156d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki    public static ShortcutLauncher loadFromXml(XmlPullParser parser, int ownerUserId)
1573145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            throws IOException, XmlPullParserException {
1583145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        final String launcherPackageName = ShortcutService.parseStringAttribute(parser,
1593145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                ATTR_PACKAGE_NAME);
160d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki        final int launcherUserId = ShortcutService.parseIntAttribute(parser,
161d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki                ATTR_LAUNCHER_USER_ID, ownerUserId);
1623145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
163d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki        final ShortcutLauncher ret = new ShortcutLauncher(launcherUserId, launcherPackageName,
164d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki                launcherUserId);
1653145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1663145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        ArraySet<String> ids = null;
1673145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        final int outerDepth = parser.getDepth();
1683145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        int type;
1693145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1703145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1713145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            if (type != XmlPullParser.START_TAG) {
1723145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                continue;
1733145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            }
1743145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final int depth = parser.getDepth();
1753145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final String tag = parser.getName();
1763145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            switch (tag) {
1773145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                case TAG_PACKAGE: {
1783145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    final String packageName = ShortcutService.parseStringAttribute(parser,
1793145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                            ATTR_PACKAGE_NAME);
1803145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    ids = new ArraySet<>();
1813145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    ret.mPinnedShortcuts.put(packageName, ids);
1823145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    continue;
1833145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                }
1843145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                case TAG_PIN: {
1853145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    ids.add(ShortcutService.parseStringAttribute(parser,
1863145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                            ATTR_VALUE));
1873145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                    continue;
1883145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                }
1893145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            }
1903145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            throw ShortcutService.throwForInvalidTag(depth, tag);
1913145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        }
1923145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        return ret;
1933145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    }
1943145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1953145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    public void dump(@NonNull ShortcutService s, @NonNull PrintWriter pw, @NonNull String prefix) {
1963145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        pw.println();
1973145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
1983145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        pw.print(prefix);
1993145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        pw.print("Launcher: ");
2003145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        pw.print(mPackageName);
201d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki        pw.print("  UserId: ");
202d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki        pw.print(mLauncherUserId);
2033145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        pw.println();
2043145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
2053145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        final int size = mPinnedShortcuts.size();
2063145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        for (int i = 0; i < size; i++) {
2073145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            pw.println();
2083145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
2093145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            pw.print(prefix);
2103145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            pw.print("  ");
2113145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            pw.print("Package: ");
2123145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            pw.println(mPinnedShortcuts.keyAt(i));
2133145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
2143145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final ArraySet<String> ids = mPinnedShortcuts.valueAt(i);
2153145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            final int idSize = ids.size();
2163145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki
2173145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            for (int j = 0; j < idSize; j++) {
2183145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                pw.print(prefix);
2190acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki                pw.print("    Pinned: ");
2203145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                pw.print(ids.valueAt(j));
2213145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki                pw.println();
2223145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki            }
2233145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki        }
2243145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki    }
2253145924596ad0db9e8f1f5aead90fb50127243cbMakoto Onuki}
226