blob: 740a8f7681398a916029e915b1a320f381a47829 [file] [log] [blame]
Makoto Onuki31459242016-03-22 11:12:18 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.pm;
17
18import android.annotation.NonNull;
19import android.annotation.UserIdInt;
20import android.content.pm.ShortcutInfo;
21import android.util.ArrayMap;
22import android.util.ArraySet;
23
24import org.xmlpull.v1.XmlPullParser;
25import org.xmlpull.v1.XmlPullParserException;
26import org.xmlpull.v1.XmlSerializer;
27
28import java.io.IOException;
29import java.io.PrintWriter;
30import java.util.List;
31
32/**
33 * Launcher information used by {@link ShortcutService}.
34 */
Makoto Onuki0acbb142016-03-22 17:02:57 -070035class ShortcutLauncher implements ShortcutPackageItem {
Makoto Onuki31459242016-03-22 11:12:18 -070036 private static final String TAG = ShortcutService.TAG;
37
38 static final String TAG_ROOT = "launcher-pins";
39
40 private static final String TAG_PACKAGE = "package";
41 private static final String TAG_PIN = "pin";
42
43 private static final String ATTR_VALUE = "value";
44 private static final String ATTR_PACKAGE_NAME = "package-name";
45
46 @UserIdInt
Makoto Onuki0acbb142016-03-22 17:02:57 -070047 private final int mUserId;
Makoto Onuki31459242016-03-22 11:12:18 -070048
49 @NonNull
Makoto Onuki0acbb142016-03-22 17:02:57 -070050 private final String mPackageName;
Makoto Onuki31459242016-03-22 11:12:18 -070051
52 /**
53 * Package name -> IDs.
54 */
55 final private ArrayMap<String, ArraySet<String>> mPinnedShortcuts = new ArrayMap<>();
56
57 ShortcutLauncher(@UserIdInt int userId, @NonNull String packageName) {
58 mUserId = userId;
59 mPackageName = packageName;
60 }
61
Makoto Onuki0acbb142016-03-22 17:02:57 -070062 @UserIdInt
63 public int getUserId() {
64 return mUserId;
65 }
66
67 @NonNull
68 public String getPackageName() {
69 return mPackageName;
70 }
71
Makoto Onuki31459242016-03-22 11:12:18 -070072 public void pinShortcuts(@NonNull ShortcutService s, @NonNull String packageName,
73 @NonNull List<String> ids) {
74 final int idSize = ids.size();
75 if (idSize == 0) {
76 mPinnedShortcuts.remove(packageName);
77 } else {
78 final ArraySet<String> prevSet = mPinnedShortcuts.get(packageName);
79
80 // Pin shortcuts. Make sure only pin the ones that were visible to the caller.
81 // i.e. a non-dynamic, pinned shortcut by *other launchers* shouldn't be pinned here.
82
83 final ShortcutPackage packageShortcuts =
84 s.getPackageShortcutsLocked(packageName, mUserId);
85 final ArraySet<String> newSet = new ArraySet<>();
86
87 for (int i = 0; i < idSize; i++) {
88 final String id = ids.get(i);
89 final ShortcutInfo si = packageShortcuts.findShortcutById(id);
90 if (si == null) {
91 continue;
92 }
93 if (si.isDynamic() || (prevSet != null && prevSet.contains(id))) {
94 newSet.add(id);
95 }
96 }
97 mPinnedShortcuts.put(packageName, newSet);
98 }
99 s.getPackageShortcutsLocked(packageName, mUserId).refreshPinnedFlags(s);
100 }
101
102 /**
103 * Return the pinned shortcut IDs for the publisher package.
104 */
105 public ArraySet<String> getPinnedShortcutIds(@NonNull String packageName) {
106 return mPinnedShortcuts.get(packageName);
107 }
108
109 boolean cleanUpPackage(String packageName) {
110 return mPinnedShortcuts.remove(packageName) != null;
111 }
112
113 /**
114 * Persist.
115 */
Makoto Onuki0acbb142016-03-22 17:02:57 -0700116 public void saveToXml(XmlSerializer out, boolean forBackup) throws IOException {
Makoto Onuki31459242016-03-22 11:12:18 -0700117 final int size = mPinnedShortcuts.size();
118 if (size == 0) {
119 return; // Nothing to write.
120 }
121
122 out.startTag(null, TAG_ROOT);
123 ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME,
124 mPackageName);
125
126 for (int i = 0; i < size; i++) {
127 out.startTag(null, TAG_PACKAGE);
128 ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME,
129 mPinnedShortcuts.keyAt(i));
130
131 final ArraySet<String> ids = mPinnedShortcuts.valueAt(i);
132 final int idSize = ids.size();
133 for (int j = 0; j < idSize; j++) {
134 ShortcutService.writeTagValue(out, TAG_PIN, ids.valueAt(j));
135 }
136 out.endTag(null, TAG_PACKAGE);
137 }
138
139 out.endTag(null, TAG_ROOT);
140 }
141
142 /**
143 * Load.
144 */
145 public static ShortcutLauncher loadFromXml(XmlPullParser parser, int userId)
146 throws IOException, XmlPullParserException {
147 final String launcherPackageName = ShortcutService.parseStringAttribute(parser,
148 ATTR_PACKAGE_NAME);
149
150 final ShortcutLauncher ret = new ShortcutLauncher(userId, launcherPackageName);
151
152 ArraySet<String> ids = null;
153 final int outerDepth = parser.getDepth();
154 int type;
155 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
156 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
157 if (type != XmlPullParser.START_TAG) {
158 continue;
159 }
160 final int depth = parser.getDepth();
161 final String tag = parser.getName();
162 switch (tag) {
163 case TAG_PACKAGE: {
164 final String packageName = ShortcutService.parseStringAttribute(parser,
165 ATTR_PACKAGE_NAME);
166 ids = new ArraySet<>();
167 ret.mPinnedShortcuts.put(packageName, ids);
168 continue;
169 }
170 case TAG_PIN: {
171 ids.add(ShortcutService.parseStringAttribute(parser,
172 ATTR_VALUE));
173 continue;
174 }
175 }
176 throw ShortcutService.throwForInvalidTag(depth, tag);
177 }
178 return ret;
179 }
180
181 public void dump(@NonNull ShortcutService s, @NonNull PrintWriter pw, @NonNull String prefix) {
182 pw.println();
183
184 pw.print(prefix);
185 pw.print("Launcher: ");
186 pw.print(mPackageName);
187 pw.println();
188
189 final int size = mPinnedShortcuts.size();
190 for (int i = 0; i < size; i++) {
191 pw.println();
192
193 pw.print(prefix);
194 pw.print(" ");
195 pw.print("Package: ");
196 pw.println(mPinnedShortcuts.keyAt(i));
197
198 final ArraySet<String> ids = mPinnedShortcuts.valueAt(i);
199 final int idSize = ids.size();
200
201 for (int j = 0; j < idSize; j++) {
202 pw.print(prefix);
Makoto Onuki0acbb142016-03-22 17:02:57 -0700203 pw.print(" Pinned: ");
Makoto Onuki31459242016-03-22 11:12:18 -0700204 pw.print(ids.valueAt(j));
205 pw.println();
206 }
207 }
208 }
209}