LauncherAppsService.java revision a6be88a10d6f6391b09f626ead051d0c698fb2d1
14f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/* 24f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Copyright (C) 2014 The Android Open Source Project 34f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * 44f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); 54f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * you may not use this file except in compliance with the License. 64f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * You may obtain a copy of the License at 74f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * 84f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * http://www.apache.org/licenses/LICENSE-2.0 94f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * 104f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Unless required by applicable law or agreed to in writing, software 114f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, 124f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * See the License for the specific language governing permissions and 144f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * limitations under the License. 154f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */ 164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasanipackage com.android.server.pm; 184f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 196f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.annotation.NonNull; 206f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.annotation.UserIdInt; 2183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onukiimport android.app.ActivityManager; 22ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onukiimport android.app.ActivityManagerInternal; 2353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.app.AppGlobals; 24a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyalimport android.app.PendingIntent; 254f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.ComponentName; 264f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.Context; 274f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.Intent; 28a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyalimport android.content.IntentSender; 2953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.ActivityInfo; 30772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guyimport android.content.pm.ApplicationInfo; 314f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.ILauncherApps; 324f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.IOnAppsChangedListener; 3353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.IPackageManager; 344dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onukiimport android.content.pm.LauncherApps.ShortcutQuery; 3553fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.PackageInfo; 36cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkeyimport android.content.pm.PackageManager; 376f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.PackageManager.NameNotFoundException; 386cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyalimport android.content.pm.ParceledListSlice; 394f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.ResolveInfo; 406f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutInfo; 416f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutServiceInternal; 426f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; 434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.UserInfo; 444f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.graphics.Rect; 45466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guyimport android.net.Uri; 464f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Binder; 474f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Bundle; 48c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onukiimport android.os.Handler; 494f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.IInterface; 505504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onukiimport android.os.ParcelFileDescriptor; 514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteCallbackList; 524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteException; 534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserHandle; 544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserManager; 55466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guyimport android.provider.Settings; 56932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasaniimport android.util.Log; 574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.util.Slog; 584f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 597a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onukiimport com.android.internal.annotations.VisibleForTesting; 604f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport com.android.internal.content.PackageMonitor; 61c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onukiimport com.android.internal.os.BackgroundThread; 626f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport com.android.internal.util.Preconditions; 636f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport com.android.server.LocalServices; 64df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasaniimport com.android.server.SystemService; 654f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 66ac21497f174504472e92b99500709518b8ab2d71Makoto Onukiimport java.util.ArrayList; 674f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.List; 684f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/** 704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Service that manages requests and callbacks for launchers that support 716f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki * managed profiles. 724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */ 73df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasanipublic class LauncherAppsService extends SystemService { 74df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 75df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final LauncherAppsImpl mLauncherAppsImpl; 764f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani public LauncherAppsService(Context context) { 78df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super(context); 79df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mLauncherAppsImpl = new LauncherAppsImpl(context); 804f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 83df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onStart() { 84df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl); 85df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 86df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 874dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki static class BroadcastCookie { 884dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public final UserHandle user; 894dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public final String packageName; 904dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 914dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie(UserHandle userHandle, String packageName) { 924dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki this.user = userHandle; 934dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki this.packageName = packageName; 944dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 954dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 964dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 977a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting 986f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki static class LauncherAppsImpl extends ILauncherApps.Stub { 99df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private static final boolean DEBUG = false; 100df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private static final String TAG = "LauncherAppsService"; 101df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final Context mContext; 102df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final PackageManager mPm; 103df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final UserManager mUm; 104ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki private final ActivityManagerInternal mActivityManagerInternal; 1056f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki private final ShortcutServiceInternal mShortcutServiceInternal; 106df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final PackageCallbackList<IOnAppsChangedListener> mListeners 107df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani = new PackageCallbackList<IOnAppsChangedListener>(); 108df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 1096f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor(); 110df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 111c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki private final Handler mCallbackHandler; 112c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki 113df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public LauncherAppsImpl(Context context) { 114df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mContext = context; 115df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mPm = mContext.getPackageManager(); 116df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 117ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki mActivityManagerInternal = Preconditions.checkNotNull( 118ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki LocalServices.getService(ActivityManagerInternal.class)); 1196f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki mShortcutServiceInternal = Preconditions.checkNotNull( 1206f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki LocalServices.getService(ShortcutServiceInternal.class)); 1216f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki mShortcutServiceInternal.addListener(mPackageMonitor); 122c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mCallbackHandler = BackgroundThread.getHandler(); 123df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 124df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 1252d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki @VisibleForTesting 1262d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki int injectBinderCallingUid() { 1272d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki return getCallingUid(); 1282d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 1292d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 130ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki final int injectCallingUserId() { 131ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return UserHandle.getUserId(injectBinderCallingUid()); 132ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 133ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 134ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki @VisibleForTesting 135ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long injectClearCallingIdentity() { 136ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return Binder.clearCallingIdentity(); 137ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 138ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 139ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki // Injection point. 140ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki @VisibleForTesting 141ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki void injectRestoreCallingIdentity(long token) { 142ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki Binder.restoreCallingIdentity(token); 143ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 144ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 1452d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki private int getCallingUserId() { 1462d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki return UserHandle.getUserId(injectBinderCallingUid()); 1472d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 1482d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 149df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /* 150df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * @see android.content.pm.ILauncherApps#addOnAppsChangedListener( 151df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * android.content.pm.IOnAppsChangedListener) 152df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 153df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 1544dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener) 1554dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki throws RemoteException { 1565ba0d3e3a3035b67d2ce3a59975145b1e0061ef4Makoto Onuki verifyCallingPackage(callingPackage); 157df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 158932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani if (DEBUG) { 159df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle()); 160932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 161df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 162df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 163df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Starting package monitoring"); 164df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 165df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani startWatchingPackageBroadcasts(); 166df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 167df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.unregister(listener); 1684dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki mListeners.register(listener, new BroadcastCookie(UserHandle.of(getCallingUserId()), 1694dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki callingPackage)); 1704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 173df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /* 174df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener( 175df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * android.content.pm.IOnAppsChangedListener) 176df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 177df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 178df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void removeOnAppsChangedListener(IOnAppsChangedListener listener) 179df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 180df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 181df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 182df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Removing listener from " + Binder.getCallingUserHandle()); 183df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 184df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.unregister(listener); 185df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 186df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani stopWatchingPackageBroadcasts(); 187df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 1884f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1904f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 191df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 192df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Register a receiver to watch for package broadcasts 193df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 194df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private void startWatchingPackageBroadcasts() { 195c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mPackageMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler); 196932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 1974f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 198df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 199df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Unregister package broadcast receiver 200df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 201df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private void stopWatchingPackageBroadcasts() { 202932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani if (DEBUG) { 203df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Stopped watching for packages"); 2044f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 205df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mPackageMonitor.unregister(); 2064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2074f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 208df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani void checkCallbackCount() { 209df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 210df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 211df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Callback count = " + mListeners.getRegisteredCallbackCount()); 212df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 213df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 214df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani stopWatchingPackageBroadcasts(); 215df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 2164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2184f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 219df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 220df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Checks if the caller is in the same group as the userToCheck. 221df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 222ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki private void ensureInUserProfiles(UserHandle userToCheck, String message) { 223abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureInUserProfiles(userToCheck.getIdentifier(), message); 224abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 225abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 226abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki private void ensureInUserProfiles(int targetUserId, String message) { 227ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki final int callingUserId = injectCallingUserId(); 228cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 229df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (targetUserId == callingUserId) return; 2304f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 231ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 232df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 233df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); 234df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); 235df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (targetUserInfo == null 236df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 237df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { 238df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throw new SecurityException(message); 239df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 240df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 241ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 242df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 243cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina } 2444f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 2457a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting // We override it in unit tests 2467a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki void verifyCallingPackage(String callingPackage) { 2476f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki int packageUid = -1; 2486f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki try { 2493ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki packageUid = mPm.getPackageUidAsUser(callingPackage, 2508a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 2518a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE 2523ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki | PackageManager.MATCH_UNINSTALLED_PACKAGES, 2533ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki UserHandle.getUserId(getCallingUid())); 2546f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } catch (NameNotFoundException e) { 2556f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki Log.e(TAG, "Package not found: " + callingPackage); 2566f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2576f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki if (packageUid != Binder.getCallingUid()) { 2586f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki throw new SecurityException("Calling package name mismatch"); 2596f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2606f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2616f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 262df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 263df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Checks if the user is enabled. 264df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 265df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private boolean isUserEnabled(UserHandle user) { 266abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki return isUserEnabled(user.getIdentifier()); 267abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 268abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 269abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki private boolean isUserEnabled(int userId) { 270ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 271df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 272abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki UserInfo targetUserInfo = mUm.getUserInfo(userId); 273df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return targetUserInfo != null && targetUserInfo.isEnabled(); 274df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 275ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 276df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 2774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 279df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 2806cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal public ParceledListSlice<ResolveInfo> getLauncherActivities(String packageName, UserHandle user) 281df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 282a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return queryActivitiesForUser( 283a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal new Intent(Intent.ACTION_MAIN) 284a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal .addCategory(Intent.CATEGORY_LAUNCHER) 285a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal .setPackage(packageName), 286a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal user); 287a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 288a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 289a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal @Override 290a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal public ActivityInfo resolveActivity(ComponentName component, UserHandle user) 291a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal throws RemoteException { 292a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal ensureInUserProfiles(user, "Cannot resolve activity for unrelated profile " + user); 293df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 2946cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal return null; 295df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 296cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 297df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 298df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 299a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal IPackageManager pm = AppGlobals.getPackageManager(); 300a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return pm.getActivityInfo(component, 3018a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3028a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3038a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 304df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 305df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 306df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 30753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 30853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 309df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 310a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal public ParceledListSlice getShortcutConfigActivities(String packageName, UserHandle user) 311df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 312a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return queryActivitiesForUser( 313a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName), user); 314a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 315a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 316a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal private ParceledListSlice<ResolveInfo> queryActivitiesForUser(Intent intent, 317a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal UserHandle user) { 318a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal ensureInUserProfiles(user, "Cannot retrieve activities for unrelated profile " + user); 319df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 320df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return null; 321df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 322cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 323a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal long ident = injectClearCallingIdentity(); 324df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 325a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(intent, 3268a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3278a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3288a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 329a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return new ParceledListSlice<>(apps); 330df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 331a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal injectRestoreCallingIdentity(ident); 332a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 333a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 334a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 335a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal @Override 336a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal public IntentSender getShortcutConfigActivityIntent(String callingPackage, 337a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal ComponentName component, UserHandle user) throws RemoteException { 338a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal ensureShortcutPermission(callingPackage, user); 339a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Preconditions.checkNotNull(component); 340a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Preconditions.checkArgument(isUserEnabled(user), "User not enabled"); 341a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 342a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal // All right, create the sender. 343a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component); 344a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal final long identity = Binder.clearCallingIdentity(); 345a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal try { 346a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return PendingIntent.getActivityAsUser( 347a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT 348a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT, 349a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal null, user) 350a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal .getIntentSender(); 351a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } finally { 352a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Binder.restoreCallingIdentity(identity); 353df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 35453fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 35553fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 356df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 357df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public boolean isPackageEnabled(String packageName, UserHandle user) 358df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 359df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user); 360df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 361df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 362df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 3634f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 364df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 365df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 366df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IPackageManager pm = AppGlobals.getPackageManager(); 367cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey PackageInfo info = pm.getPackageInfo(packageName, 3688a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3698a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3708a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 371df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return info != null && info.applicationInfo.enabled; 372df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 373df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 374df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 3754f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 3764f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 377df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 378772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) 379772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy throws RemoteException { 380772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user); 381772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy if (!isUserEnabled(user)) { 382772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return null; 383772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 384772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 385772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy long ident = Binder.clearCallingIdentity(); 386772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy try { 387772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy IPackageManager pm = AppGlobals.getPackageManager(); 388772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy ApplicationInfo info = pm.getApplicationInfo(packageName, flags, 389772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy user.getIdentifier()); 390772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return info; 391772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } finally { 392772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy Binder.restoreCallingIdentity(ident); 393772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 394772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 395772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 3962d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki private void ensureShortcutPermission(@NonNull String callingPackage, UserHandle user) { 397abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureShortcutPermission(callingPackage, user.getIdentifier()); 398abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 399abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 400abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki private void ensureShortcutPermission(@NonNull String callingPackage, int userId) { 4012d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 402b5fc2e6706dfa9884ee9d5ab802c9a66c370e9cbMakoto Onuki ensureInUserProfiles(userId, "Cannot access shortcuts for unrelated profile " + userId); 4032d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 404d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 405d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage)) { 4062d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki throw new SecurityException("Caller can't access shortcut information"); 4072d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 4086f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4096f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4106f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4116f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public ParceledListSlice getShortcuts(String callingPackage, long changedSince, 412abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki String packageName, List shortcutIds, ComponentName componentName, int flags, 413abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki UserHandle user) { 4142d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 415ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 416ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return new ParceledListSlice<>(new ArrayList(0)); 417ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 418abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (shortcutIds != null && packageName == null) { 419abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki throw new IllegalArgumentException( 420abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki "To query by shortcut ID, package name must also be set"); 421abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 4226f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 423f93ce176dec4691165c78bf25fe36fbf3a93a096Felipe Leme // TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below. 424f93ce176dec4691165c78bf25fe36fbf3a93a096Felipe Leme return new ParceledListSlice<>((List<ShortcutInfo>) 425d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.getShortcuts(getCallingUserId(), 426abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, changedSince, packageName, shortcutIds, 427d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki componentName, flags, user.getIdentifier())); 4286f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4296f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4306f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4316f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void pinShortcuts(String callingPackage, String packageName, List<String> ids, 432d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki UserHandle user) { 4332d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 434ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 435ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot pin shortcuts for disabled profile " 436ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki + user); 437ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4386f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 439d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.pinShortcuts(getCallingUserId(), 440d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, packageName, ids, user.getIdentifier()); 4416f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4426f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4436f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 444abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki public int getShortcutIconResId(String callingPackage, String packageName, String id, 445abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki int userId) { 446abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureShortcutPermission(callingPackage, userId); 447abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (!isUserEnabled(userId)) { 448ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return 0; 449ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4505504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 451d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(), 452abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, packageName, id, userId); 4535504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 4545504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 4555504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 456abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki public ParcelFileDescriptor getShortcutIconFd(String callingPackage, 457abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki String packageName, String id, int userId) { 458abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureShortcutPermission(callingPackage, userId); 459abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (!isUserEnabled(userId)) { 460ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return null; 461ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4625504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 463d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(), 464abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, packageName, id, userId); 4655504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 4665504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 4675504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 468d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki public boolean hasShortcutHostPermission(String callingPackage) { 4692d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 470d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 471d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage); 4722d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 4732d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 4742d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki @Override 47583f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki public boolean startShortcut(String callingPackage, String packageName, String shortcutId, 476abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki Rect sourceBounds, Bundle startActivityOptions, int userId) { 477d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki verifyCallingPackage(callingPackage); 478abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureInUserProfiles(userId, "Cannot start activity for unrelated profile " + userId); 479d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki 480abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (!isUserEnabled(userId)) { 481ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot start a shortcut for disabled profile " 482abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki + userId); 483ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 484ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 485d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki // Even without the permission, pinned shortcuts are always launchable. 486d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), 487abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, packageName, shortcutId, userId)) { 488abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureShortcutPermission(callingPackage, userId); 489d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki } 4906f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 491440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki final Intent[] intents = mShortcutServiceInternal.createShortcutIntents( 492440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki getCallingUserId(), callingPackage, packageName, shortcutId, userId); 493440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki if (intents == null || intents.length == 0) { 49483f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return false; 49543204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 49643204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki // Note the target activity doesn't have to be exported. 49743204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki 4987e5c3e85420a255bd79242dd97b90340c6e3a4dfMakoto Onuki intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 4990eed441c0cf3bd03b8ac780e62fbeae5d7fcac4bMakoto Onuki intents[0].setSourceBounds(sourceBounds); 500440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki 501440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki return startShortcutIntentsAsPublisher( 502440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki intents, packageName, startActivityOptions, userId); 503ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki } 504ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki 505440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents, 506ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki @NonNull String publisherPackage, Bundle startActivityOptions, int userId) { 50783f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki final int code; 50883f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki final long ident = injectClearCallingIdentity(); 50943204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki try { 510440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki code = mActivityManagerInternal.startActivitiesAsPackage(publisherPackage, 511440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki userId, intents, startActivityOptions); 51283f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki if (code >= ActivityManager.START_SUCCESS) { 51383f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return true; // Success 51483f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } else { 51583f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki Log.e(TAG, "Couldn't start activity, code=" + code); 516ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki } 51783f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return code >= ActivityManager.START_SUCCESS; 51883f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } catch (SecurityException e) { 51983f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki if (DEBUG) { 52083f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki Slog.d(TAG, "SecurityException while launching intent", e); 52183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } 52283f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return false; 52383f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } finally { 52483f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki injectRestoreCallingIdentity(ident); 52543204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 5266f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 5276f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 528772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 529df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public boolean isActivityEnabled(ComponentName component, UserHandle user) 530df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 531df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani ensureInUserProfiles(user, "Cannot check component for unrelated profile " + user); 532df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 533df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 534932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 535df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 536932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani long ident = Binder.clearCallingIdentity(); 537932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani try { 538df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IPackageManager pm = AppGlobals.getPackageManager(); 539cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey ActivityInfo info = pm.getActivityInfo(component, 5408a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5418a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 5428a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 543dcf21d15456e5aca28d063aea73139e30842e6d1Winson Chung return info != null; 544932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } finally { 545932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani Binder.restoreCallingIdentity(ident); 546932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 547932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 548932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani 5494f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 550df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void startActivityAsUser(ComponentName component, Rect sourceBounds, 551df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Bundle opts, UserHandle user) throws RemoteException { 552df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user); 553df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 554df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throw new IllegalStateException("Cannot start activity for disabled profile " + user); 5554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 5564f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 557df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Intent launchIntent = new Intent(Intent.ACTION_MAIN); 558df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); 559347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki launchIntent.setSourceBounds(sourceBounds); 560347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 561347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 5622df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setPackage(component.getPackageName()); 563df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 564df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 565df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 5662df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy IPackageManager pm = AppGlobals.getPackageManager(); 567cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey ActivityInfo info = pm.getActivityInfo(component, 5688a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5698a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 5708a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 5712df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (!info.exported) { 5722df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Cannot launch non-exported components " 5732df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + component); 5742df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 5752df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy 5762df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Check that the component actually has Intent.CATEGORY_LAUCNCHER 5772df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // as calling startActivityAsUser ignores the category and just 5782df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // resolves based on the component if present. 5792df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent, 5808a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5818a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 5828a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 5832df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy final int size = apps.size(); 5842df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy for (int i = 0; i < size; ++i) { 5852df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy ActivityInfo activityInfo = apps.get(i).activityInfo; 5862df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (activityInfo.packageName.equals(component.getPackageName()) && 5872df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy activityInfo.name.equals(component.getClassName())) { 5882df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Found an activity with category launcher that matches 5892df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // this component so ok to launch. 5902df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setComponent(component); 5912df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy mContext.startActivityAsUser(launchIntent, opts, user); 5922df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy return; 5932df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 5942df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 5952df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Attempt to launch activity without " 5962df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + " category Intent.CATEGORY_LAUNCHER " + component); 597df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 598df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 599df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6004f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6014f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 602466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy @Override 603466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy public void showAppDetailsAsUser(ComponentName component, Rect sourceBounds, 604466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Bundle opts, UserHandle user) throws RemoteException { 605466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy ensureInUserProfiles(user, "Cannot show app details for unrelated profile " + user); 606466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy if (!isUserEnabled(user)) { 607466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy throw new IllegalStateException("Cannot show app details for disabled profile " 608466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy + user); 609466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 610466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 611466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy long ident = Binder.clearCallingIdentity(); 612466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy try { 613466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy String packageName = component.getPackageName(); 614466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, 615466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Uri.fromParts("package", packageName, null)); 616369aad0e23a1ca1417018c540730915760fe2ed3Winson intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 617466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy intent.setSourceBounds(sourceBounds); 618466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy mContext.startActivityAsUser(intent, opts, user); 619466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } finally { 620466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Binder.restoreCallingIdentity(ident); 621466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 622466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 623466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 6244dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki /** Checks if user is a profile of or same as listeningUser. 6254dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki * and the user is enabled. */ 626ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, 6274dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki String debugMsg) { 6284dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (user.getIdentifier() == listeningUser.getIdentifier()) { 6294dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg); 6304dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 6314dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 632ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 6334dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki try { 6344dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo userInfo = mUm.getUserInfo(user.getIdentifier()); 6354dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); 6364dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (userInfo == null || listeningUserInfo == null 6374dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 6384dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId != listeningUserInfo.profileGroupId 6394dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || !userInfo.isEnabled()) { 6404dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 6414dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":" 6424dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 643df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6444dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return false; 6454dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } else { 6464dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 6474dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":" 6484dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 6494dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 6504dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 6514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6524dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } finally { 653ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 6544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6554dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 6564dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 657c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki @VisibleForTesting 658aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki void postToPackageMonitorHandler(Runnable r) { 659c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mCallbackHandler.post(r); 6604dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 6614dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 6624dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener { 6634f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 6646f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki // TODO Simplify with lambdas. 6656f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 666df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 667df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageAdded(String packageName, int uid) { 668df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 669df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 6707bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 6717bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 6727bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 6737bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 6747bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageAdded")) continue; 6757bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 6767bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageAdded(user, packageName); 6777bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 6787bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 6797bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 680df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6817bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 6827bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 6834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 684df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 685df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageAdded(packageName, uid); 6864f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 688df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 689df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageRemoved(String packageName, int uid) { 690df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 691df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 6927bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 6937bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 6947bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 6957bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 6967bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageRemoved")) continue; 6977bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 6987bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageRemoved(user, packageName); 6997bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7007bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7017bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 702df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7037bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7047bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 705df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 707df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageRemoved(packageName, uid); 708df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 709df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 710df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 711df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageModified(String packageName) { 712df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 713df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7147bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7157bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7167bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7177bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7187bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageModified")) continue; 7197bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7207bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageChanged(user, packageName); 7217bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7227bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7237bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 724df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7257bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7267bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 7274f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 728df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 729df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageModified(packageName); 7304f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7314f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 732df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 733df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesAvailable(String[] packages) { 734df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 735df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7367bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7377bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7387bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7397bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7407bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesAvailable")) continue; 7417bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7427bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesAvailable(user, packages, isReplacing()); 7437bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7447bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7457bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 746df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7477bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7487bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 749df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7504f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 751df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesAvailable(packages); 752df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 753df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 754df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 755df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesUnavailable(String[] packages) { 756df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 757df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7587bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7597bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7607bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7617bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7627bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnavailable")) continue; 7637bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7647bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesUnavailable(user, packages, isReplacing()); 7657bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7667bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7677bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 768df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7697bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7707bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 7714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 772df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 773df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesUnavailable(packages); 7744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7754f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 776772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 777772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesSuspended(String[] packages) { 778772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 779772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 7807bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7817bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7827bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7837bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7847bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesSuspended")) continue; 7857bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7867bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesSuspended(user, packages); 7877bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7887bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7897bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 790772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 7917bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7927bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 793772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 794772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 795772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesSuspended(packages); 796772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 797772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 798772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 799772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesUnsuspended(String[] packages) { 800772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 801772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 8027bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8037bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8047bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8057bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8067bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnsuspended")) continue; 8077bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8087bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesUnsuspended(user, packages); 8097bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8107bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8117bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 812772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 8137bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8147bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 815772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 816772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 817772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesUnsuspended(packages); 818772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 819772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 8206f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 8216f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void onShortcutChanged(@NonNull String packageName, 8224dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 823aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId)); 8244dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 8254dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 8264dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private void onShortcutChangedInner(@NonNull String packageName, 8274dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 8287bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki final int n = mListeners.beginBroadcast(); 82902f338e23d06499790c6948709afb1587416eb40Makoto Onuki try { 83002f338e23d06499790c6948709afb1587416eb40Makoto Onuki final UserHandle user = UserHandle.of(userId); 83102f338e23d06499790c6948709afb1587416eb40Makoto Onuki 83202f338e23d06499790c6948709afb1587416eb40Makoto Onuki for (int i = 0; i < n; i++) { 83302f338e23d06499790c6948709afb1587416eb40Makoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 83402f338e23d06499790c6948709afb1587416eb40Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 83502f338e23d06499790c6948709afb1587416eb40Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue; 83602f338e23d06499790c6948709afb1587416eb40Makoto Onuki 83702f338e23d06499790c6948709afb1587416eb40Makoto Onuki final int launcherUserId = cookie.user.getIdentifier(); 83802f338e23d06499790c6948709afb1587416eb40Makoto Onuki 83902f338e23d06499790c6948709afb1587416eb40Makoto Onuki // Make sure the caller has the permission. 84002f338e23d06499790c6948709afb1587416eb40Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission( 84102f338e23d06499790c6948709afb1587416eb40Makoto Onuki launcherUserId, cookie.packageName)) { 84202f338e23d06499790c6948709afb1587416eb40Makoto Onuki continue; 84302f338e23d06499790c6948709afb1587416eb40Makoto Onuki } 84402f338e23d06499790c6948709afb1587416eb40Makoto Onuki // Each launcher has a different set of pinned shortcuts, so we need to do a 84502f338e23d06499790c6948709afb1587416eb40Makoto Onuki // query in here. 84602f338e23d06499790c6948709afb1587416eb40Makoto Onuki // (As of now, only one launcher has the permission at a time, so it's bit 84702f338e23d06499790c6948709afb1587416eb40Makoto Onuki // moot, but we may change the permission model eventually.) 84802f338e23d06499790c6948709afb1587416eb40Makoto Onuki final List<ShortcutInfo> list = 84902f338e23d06499790c6948709afb1587416eb40Makoto Onuki mShortcutServiceInternal.getShortcuts(launcherUserId, 85002f338e23d06499790c6948709afb1587416eb40Makoto Onuki cookie.packageName, 85102f338e23d06499790c6948709afb1587416eb40Makoto Onuki /* changedSince= */ 0, packageName, /* shortcutIds=*/ null, 85202f338e23d06499790c6948709afb1587416eb40Makoto Onuki /* component= */ null, 85302f338e23d06499790c6948709afb1587416eb40Makoto Onuki ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY 85402f338e23d06499790c6948709afb1587416eb40Makoto Onuki | ShortcutQuery.FLAG_GET_ALL_KINDS 85502f338e23d06499790c6948709afb1587416eb40Makoto Onuki , userId); 85602f338e23d06499790c6948709afb1587416eb40Makoto Onuki try { 85702f338e23d06499790c6948709afb1587416eb40Makoto Onuki listener.onShortcutChanged(user, packageName, 85802f338e23d06499790c6948709afb1587416eb40Makoto Onuki new ParceledListSlice<>(list)); 85902f338e23d06499790c6948709afb1587416eb40Makoto Onuki } catch (RemoteException re) { 86002f338e23d06499790c6948709afb1587416eb40Makoto Onuki Slog.d(TAG, "Callback failed ", re); 86102f338e23d06499790c6948709afb1587416eb40Makoto Onuki } 8626f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 86302f338e23d06499790c6948709afb1587416eb40Makoto Onuki } catch (RuntimeException e) { 86402f338e23d06499790c6948709afb1587416eb40Makoto Onuki // When the user is locked we get IllegalState, so just catch all. 86502f338e23d06499790c6948709afb1587416eb40Makoto Onuki Log.w(TAG, e.getMessage(), e); 8667bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8677bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 8686f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 8696f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 8704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 8714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 872df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> { 873df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 874df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onCallbackDied(T callback, Object cookie) { 875df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani checkCallbackCount(); 876df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 8774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 8784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 879b6830197450d5a2befaf0dc4f7e73850f4c55846Nicolas Prevot} 880