• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 package android.content.pm.cts.shortcutmanager;
17 
18 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
19 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
20 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.retryUntil;
21 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher;
22 
23 import android.content.Context;
24 import android.content.pm.LauncherApps;
25 import android.content.pm.ShortcutInfo;
26 import android.os.Handler;
27 import android.os.Looper;
28 import android.os.UserHandle;
29 import android.test.suitebuilder.annotation.SmallTest;
30 import android.util.Log;
31 
32 import com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.ShortcutListAsserter;
33 
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.HashSet;
37 import java.util.List;
38 import java.util.concurrent.atomic.AtomicBoolean;
39 import java.util.function.Predicate;
40 
41 import com.android.compatibility.common.util.CddTest;
42 
43 @CddTest(requirement="3.8.1/C-2-3")
44 @SmallTest
45 public class ShortcutManagerLauncherCallbackTest extends ShortcutManagerCtsTestsBase {
46 
47     private static class MyCallback extends LauncherApps.Callback {
48         private final HashSet<String> mInterestedPackages = new HashSet<String>();
49         private boolean called;
50         private String lastPackage;
51         private final List<ShortcutInfo> lastShortcuts = new ArrayList<>();
52 
MyCallback(String... interestedPackages)53         public MyCallback(String... interestedPackages) {
54             mInterestedPackages.addAll(Arrays.asList(interestedPackages));
55         }
56 
57         @Override
onPackageRemoved(String packageName, UserHandle user)58         public void onPackageRemoved(String packageName, UserHandle user) {
59         }
60 
61         @Override
onPackageAdded(String packageName, UserHandle user)62         public void onPackageAdded(String packageName, UserHandle user) {
63         }
64 
65         @Override
onPackageChanged(String packageName, UserHandle user)66         public void onPackageChanged(String packageName, UserHandle user) {
67         }
68 
69         @Override
onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing)70         public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
71         }
72 
73         @Override
onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing)74         public void onPackagesUnavailable(String[] packageNames, UserHandle user,
75                 boolean replacing) {
76         }
77 
78         @Override
onShortcutsChanged( String packageName, List<ShortcutInfo> shortcuts, UserHandle user)79         public synchronized void onShortcutsChanged(
80                 String packageName, List<ShortcutInfo> shortcuts, UserHandle user) {
81             if (!mInterestedPackages.contains(packageName)) {
82                 return; // Ignore other packages.
83             }
84 
85             final StringBuilder sb = new StringBuilder();
86             for (ShortcutInfo si : shortcuts) {
87                 if (sb.length() > 0) {
88                     sb.append(", ");
89                 }
90                 sb.append(si.getId());
91             }
92 
93             Log.i(TAG, "onShortcutsChanged: package="
94                     + packageName + " shortcuts=" + sb.toString());
95             for (ShortcutInfo si : shortcuts) {
96                 Log.i(TAG, "  " + si);
97             }
98             lastPackage = packageName;
99             lastShortcuts.clear();
100             lastShortcuts.addAll(shortcuts);
101             called = true;
102         }
103 
reset()104         public synchronized void reset() {
105             lastPackage = null;
106             lastShortcuts.clear();
107             called = false;
108         }
109 
isCalled()110         public synchronized boolean isCalled() {
111             return called;
112         }
113 
assertCalled(Context clientContext)114         public synchronized ShortcutListAsserter assertCalled(Context clientContext) {
115             assertEquals(clientContext.getPackageName(), lastPackage);
116             return assertWith(lastShortcuts);
117         }
118 
getList()119         public synchronized List<ShortcutInfo> getList() {
120             return lastShortcuts;
121         }
122 
isShortcutById(String id, Predicate<ShortcutInfo> predicate)123         public synchronized boolean isShortcutById(String id, Predicate<ShortcutInfo> predicate) {
124             for (ShortcutInfo si : lastShortcuts) {
125                 if (id.equals(si.getId()) && predicate.test(si)) {
126                     return true;
127                 }
128             }
129             return false;
130         }
131     }
132 
testRegisterAndUnRegister()133     public void testRegisterAndUnRegister() {
134         final MyCallback c = new MyCallback();
135         final Handler handler = new Handler(Looper.getMainLooper());
136         getLauncherApps().registerCallback(c, handler);
137         getLauncherApps().unregisterCallback(c);
138     }
139 
testCallbacks()140     public void testCallbacks() {
141         final MyCallback c = new MyCallback(mPackageContext1.getPackageName());
142 
143         setDefaultLauncher(getInstrumentation(), mLauncherContext1);
144 
145         final Handler handler = new Handler(Looper.getMainLooper());
146 
147         final AtomicBoolean registered = new AtomicBoolean(false);
148 
149         final Runnable reset = () -> {
150             runWithCaller(mLauncherContext1, () -> {
151                 if (registered.get()) {
152                     getLauncherApps().unregisterCallback(c);
153                     registered.set(false);
154                 }
155                 c.reset();
156                 getLauncherApps().registerCallback(c, handler);
157                 registered.set(true);
158             });
159         };
160         reset.run();
161         try {
162             //-----------------------
163             Log.i(TAG, "testCallbacks: setDynamicShortcuts");
164             runWithCaller(mPackageContext1, () -> {
165                 assertTrue(getManager().setDynamicShortcuts(list(
166                         makeShortcut("s1"),
167                         makeShortcut("s2")
168                 )));
169             });
170             retryUntil(() -> c.isCalled(), "callback not called.");
171             c.assertCalled(mPackageContext1)
172                     .haveIds("s1", "s2")
173                     .areAllEnabled();
174             reset.run();
175 
176             //-----------------------
177             Log.i(TAG, "testCallbacks: addDynamicShortcuts");
178             runWithCaller(mPackageContext1, () -> {
179                 assertTrue(getManager().addDynamicShortcuts(list(
180                         makeShortcutWithRank("sx", 1)
181                 )));
182             });
183             retryUntil(() -> c.isCalled(), "callback not called.");
184             c.assertCalled(mPackageContext1)
185                     .haveIds("s1", "s2", "sx")
186                     .areAllEnabled();
187             reset.run();
188 
189             //-----------------------
190             Log.i(TAG, "testCallbacks: updateShortcuts 1");
191             runWithCaller(mPackageContext1, () -> {
192                 assertTrue(getManager().updateShortcuts(list(
193                         makeShortcut("s2")
194                 )));
195             });
196             retryUntil(() -> c.isCalled(), "callback not called.");
197             c.assertCalled(mPackageContext1)
198                     .haveIds("s1", "s2", "sx")
199                     .areAllEnabled();
200             reset.run();
201 
202             //-----------------------
203             Log.i(TAG, "testCallbacks: updateShortcuts 2");
204             runWithCaller(mPackageContext1, () -> {
205                 assertTrue(getManager().updateShortcuts(list(
206                         makeShortcut("sx")
207                 )));
208             });
209             retryUntil(() -> c.isCalled(), "callback not called.");
210             c.assertCalled(mPackageContext1)
211                     .haveIds("s1", "s2", "sx")
212                     .areAllEnabled();
213             reset.run();
214 
215             //-----------------------
216             Log.i(TAG, "testCallbacks: enableManifestActivity 1");
217             runWithCaller(mPackageContext1, () -> {
218                 enableManifestActivity("Launcher_manifest_1", true);
219                 retryUntil(() -> getManager().getManifestShortcuts().size() == 1,
220                         "Manifest shortcuts didn't show up");
221             });
222             retryUntil(() -> c.isCalled(), "callback not called.");
223             c.assertCalled(mPackageContext1)
224                     .haveIds("s1", "s2", "sx", "ms1")
225                     .areAllEnabled();
226             reset.run();
227 
228             //-----------------------
229             Log.i(TAG, "testCallbacks: enableManifestActivity 2");
230             runWithCaller(mPackageContext1, () -> {
231                 enableManifestActivity("Launcher_manifest_2", true);
232                 retryUntil(() -> getManager().getManifestShortcuts().size() == 3,
233                         "Manifest shortcuts didn't show up");
234             });
235             retryUntil(() -> c.isCalled(), "callback not called.");
236             c.assertCalled(mPackageContext1)
237                     .haveIds("s1", "s2", "sx", "ms1", "ms21", "ms22")
238                     .areAllEnabled();
239             reset.run();
240 
241             //-----------------------
242             // Pin some shortcuts.
243             Log.i(TAG, "testCallbacks: pinShortcuts");
244             runWithCaller(mLauncherContext1, () -> {
245                 getLauncherApps().pinShortcuts(mPackageContext1.getPackageName(),
246                         list("s1", "ms1", "ms21"), getUserHandle());
247             });
248 
249             setDefaultLauncher(getInstrumentation(), mLauncherContext2);
250             runWithCaller(mLauncherContext2, () -> {
251                 getLauncherApps().pinShortcuts(mPackageContext1.getPackageName(),
252                         list("s1", "s2", "s3", "ms22"), getUserHandle());
253             });
254 
255             setDefaultLauncher(getInstrumentation(), mLauncherContext1);
256             reset.run();
257 
258             //-----------------------
259             Log.i(TAG, "testCallbacks: removeDynamicShortcuts");
260             runWithCaller(mPackageContext1, () -> {
261                 getManager().removeDynamicShortcuts(list("s1", "s2"));
262             });
263             retryUntil(() -> c.isCalled(), "callback not called.");
264 
265             // s2 is still pinned by L2, but not visible to L1.
266             c.assertCalled(mPackageContext1)
267                     .haveIds("s1", "sx", "ms1", "ms21", "ms22")
268                     .areAllEnabled();
269             reset.run();
270 
271             //-----------------------
272             Log.i(TAG, "testCallbacks: enableManifestActivity");
273             runWithCaller(mPackageContext1, () -> {
274                 enableManifestActivity("Launcher_manifest_2", false);
275 
276                 retryUntil(() -> getManager().getManifestShortcuts().size() == 1,
277                         "Manifest shortcuts didn't show up");
278             });
279             retryUntil(() -> c.isCalled(), "callback not called.");
280             c.assertCalled(mPackageContext1)
281                     .haveIds("s1", "sx", "ms1", "ms21")
282 
283                     .selectByIds("s1", "sx", "ms1")
284                     .areAllEnabled()
285 
286                     .revertToOriginalList()
287                     .selectByIds("ms21")
288                     .areAllDisabled();
289             reset.run();
290 
291             //-----------------------
292             Log.i(TAG, "testCallbacks: disableShortcuts");
293             runWithCaller(mPackageContext1, () -> {
294                 getManager().disableShortcuts(list("s1"));
295             });
296             retryUntil(() -> (c.isCalled() && c.isShortcutById("s1", si -> !si.isEnabled())),
297                     "s1 not disabled");
298 
299             c.assertCalled(mPackageContext1)
300                     .haveIds("s1", "sx", "ms1", "ms21")
301 
302                     .selectByIds("sx", "ms1")
303                     .areAllEnabled()
304 
305                     .revertToOriginalList()
306                     .selectByIds("s1", "ms21")
307                     .areAllDisabled();
308             reset.run();
309 
310             //-----------------------
311             Log.i(TAG, "testCallbacks: enableShortcuts 1");
312             runWithCaller(mPackageContext1, () -> {
313                 getManager().enableShortcuts(list("s1"));
314             });
315             retryUntil(() -> (c.isCalled() && c.isShortcutById("s1", si -> si.isEnabled())),
316                     "s1 not enabled");
317 
318             c.assertCalled(mPackageContext1)
319                     .haveIds("s1", "sx", "ms1", "ms21")
320 
321                     .selectByIds("s1", "sx", "ms1")
322                     .areAllEnabled()
323 
324                     .revertToOriginalList()
325                     .selectByIds("ms21")
326                     .areAllDisabled();
327             reset.run();
328 
329             //-----------------------
330             Log.i(TAG, "testCallbacks: enableShortcuts 2");
331             runWithCaller(mPackageContext1, () -> {
332                 getManager().enableShortcuts(list("s2"));
333             });
334             retryUntil(() -> c.isCalled(), "callback not called.");
335             c.assertCalled(mPackageContext1)
336                     .haveIds("s1", "sx", "ms1", "ms21")
337 
338                     .selectByIds("s1", "sx", "ms1")
339                     .areAllEnabled()
340 
341                     .revertToOriginalList()
342                     .selectByIds("ms21")
343                     .areAllDisabled();
344             reset.run();
345 
346         } finally {
347             runWithCaller(mLauncherContext1, () -> {
348                 if (registered.get()) {
349                     getLauncherApps().unregisterCallback(c);
350                     registered.set(false);
351                 }
352             });
353         }
354     }
355 }
356