LauncherAppsService.java revision 3a2541e6daec72824f0f9f8c9cd81bacac263b5c
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 */ 2223a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki private void ensureInUserProfiles( 2233a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, UserHandle userToCheck, String message) { 2243a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, userToCheck.getIdentifier(), message); 225abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 226abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 2273a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki private void ensureInUserProfiles(String callingPackage, int targetUserId, String message) { 228ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki final int callingUserId = injectCallingUserId(); 229cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 230df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (targetUserId == callingUserId) return; 2314f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 232ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 233df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 234df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); 235aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki if (callingUserInfo.isManagedProfile()) { 23686389b3edc86994b8f59a4562ce2a499294d96bfMakoto Onuki // TODO: Make it SecurityException. See b/34650921 23786389b3edc86994b8f59a4562ce2a499294d96bfMakoto Onuki // throw new SecurityException(message + " for another profile " + targetUserId); 23886389b3edc86994b8f59a4562ce2a499294d96bfMakoto Onuki 23986389b3edc86994b8f59a4562ce2a499294d96bfMakoto Onuki // TODO: Report caller package name. 2403a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki Slog.wtfStack(TAG, message + " by " + callingPackage + " for another profile " 2413a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki + targetUserId + " from " + callingUserId); 242aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki } 243aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki 244df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); 245df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (targetUserInfo == null 246df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 247df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { 248aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki throw new SecurityException(message + " for unrelated profile " + targetUserId); 249df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 250df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 251ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 252df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 253cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina } 2544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 2557a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting // We override it in unit tests 2567a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki void verifyCallingPackage(String callingPackage) { 2576f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki int packageUid = -1; 2586f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki try { 2593ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki packageUid = mPm.getPackageUidAsUser(callingPackage, 2608a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 2618a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE 2623ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki | PackageManager.MATCH_UNINSTALLED_PACKAGES, 2633ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki UserHandle.getUserId(getCallingUid())); 2646f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } catch (NameNotFoundException e) { 2656f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki Log.e(TAG, "Package not found: " + callingPackage); 2666f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2676f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki if (packageUid != Binder.getCallingUid()) { 2686f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki throw new SecurityException("Calling package name mismatch"); 2696f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2706f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2716f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 272df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 273df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Checks if the user is enabled. 274df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 275df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private boolean isUserEnabled(UserHandle user) { 276abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki return isUserEnabled(user.getIdentifier()); 277abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 278abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 279abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki private boolean isUserEnabled(int userId) { 280ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 281df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 282abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki UserInfo targetUserInfo = mUm.getUserInfo(userId); 283df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return targetUserInfo != null && targetUserInfo.isEnabled(); 284df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 285ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 286df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 2874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2884f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 289df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 2903a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage, 2913a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String packageName, UserHandle user) 292df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 2933a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki return queryActivitiesForUser(callingPackage, 294a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal new Intent(Intent.ACTION_MAIN) 295a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal .addCategory(Intent.CATEGORY_LAUNCHER) 296a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal .setPackage(packageName), 297a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal user); 298a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 299a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 300a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal @Override 3013a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ActivityInfo resolveActivity( 3023a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, ComponentName component, UserHandle user) 303a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal throws RemoteException { 3043a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, user, "Cannot resolve activity"); 305df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 3066cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal return null; 307df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 308cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 309df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 310df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 311a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal IPackageManager pm = AppGlobals.getPackageManager(); 312a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return pm.getActivityInfo(component, 3138a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3148a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3158a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 316df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 317df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 318df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 31953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 32053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 321df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 3223a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ParceledListSlice getShortcutConfigActivities( 3233a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, String packageName, UserHandle user) 324df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 3253a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki return queryActivitiesForUser(callingPackage, 326a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName), user); 327a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 328a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 3293a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage, 3303a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki Intent intent, UserHandle user) { 3313a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, user, "Cannot retrieve activities"); 332df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 333df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return null; 334df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 335cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 336a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal long ident = injectClearCallingIdentity(); 337df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 338a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(intent, 3398a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3408a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3418a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 342a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return new ParceledListSlice<>(apps); 343df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 344a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal injectRestoreCallingIdentity(ident); 345a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 346a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 347a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 348a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal @Override 349a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal public IntentSender getShortcutConfigActivityIntent(String callingPackage, 350a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal ComponentName component, UserHandle user) throws RemoteException { 351a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal ensureShortcutPermission(callingPackage, user); 352a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Preconditions.checkNotNull(component); 353a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Preconditions.checkArgument(isUserEnabled(user), "User not enabled"); 354a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 355a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal // All right, create the sender. 356a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component); 357a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal final long identity = Binder.clearCallingIdentity(); 358a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal try { 359a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return PendingIntent.getActivityAsUser( 360a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT 361a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT, 362a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal null, user) 363a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal .getIntentSender(); 364a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } finally { 365a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Binder.restoreCallingIdentity(identity); 366df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 36753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 36853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 369df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 3703a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user) 371df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 3723a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, user, "Cannot check package"); 373df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 374df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 375df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 3764f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 377df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 378df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 379df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IPackageManager pm = AppGlobals.getPackageManager(); 380cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey PackageInfo info = pm.getPackageInfo(packageName, 3818a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3828a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3838a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 384df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return info != null && info.applicationInfo.enabled; 385df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 386df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 387df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 3884f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 3894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 390df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 3913a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ApplicationInfo getApplicationInfo( 3923a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, String packageName, int flags, UserHandle user) 393772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy throws RemoteException { 3943a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, user, "Cannot check package"); 395772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy if (!isUserEnabled(user)) { 396772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return null; 397772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 398772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 399772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy long ident = Binder.clearCallingIdentity(); 400772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy try { 401772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy IPackageManager pm = AppGlobals.getPackageManager(); 402772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy ApplicationInfo info = pm.getApplicationInfo(packageName, flags, 403772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy user.getIdentifier()); 404772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return info; 405772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } finally { 406772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy Binder.restoreCallingIdentity(ident); 407772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 408772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 409772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 4102d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki private void ensureShortcutPermission(@NonNull String callingPackage, UserHandle user) { 411abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureShortcutPermission(callingPackage, user.getIdentifier()); 412abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 413abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 414abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki private void ensureShortcutPermission(@NonNull String callingPackage, int userId) { 4152d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 4163a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, userId, "Cannot access shortcuts"); 4172d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 418d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 419d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage)) { 4202d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki throw new SecurityException("Caller can't access shortcut information"); 4212d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 4226f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4236f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4246f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4256f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public ParceledListSlice getShortcuts(String callingPackage, long changedSince, 426abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki String packageName, List shortcutIds, ComponentName componentName, int flags, 427abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki UserHandle user) { 4282d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 429ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 430ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return new ParceledListSlice<>(new ArrayList(0)); 431ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 432abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (shortcutIds != null && packageName == null) { 433abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki throw new IllegalArgumentException( 434abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki "To query by shortcut ID, package name must also be set"); 435abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 4366f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 437f93ce176dec4691165c78bf25fe36fbf3a93a096Felipe Leme // TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below. 438f93ce176dec4691165c78bf25fe36fbf3a93a096Felipe Leme return new ParceledListSlice<>((List<ShortcutInfo>) 439d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.getShortcuts(getCallingUserId(), 440abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, changedSince, packageName, shortcutIds, 441d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki componentName, flags, user.getIdentifier())); 4426f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4436f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4446f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4456f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void pinShortcuts(String callingPackage, String packageName, List<String> ids, 446d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki UserHandle user) { 4472d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 448ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 449ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot pin shortcuts for disabled profile " 450ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki + user); 451ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4526f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 453d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.pinShortcuts(getCallingUserId(), 454d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, packageName, ids, user.getIdentifier()); 4556f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4566f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4576f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 458abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki public int getShortcutIconResId(String callingPackage, String packageName, String id, 459abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki int userId) { 460abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureShortcutPermission(callingPackage, userId); 461abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (!isUserEnabled(userId)) { 462ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return 0; 463ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4645504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 465d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(), 466abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, packageName, id, userId); 4675504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 4685504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 4695504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 470abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki public ParcelFileDescriptor getShortcutIconFd(String callingPackage, 471abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki String packageName, String id, int userId) { 472abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureShortcutPermission(callingPackage, userId); 473abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (!isUserEnabled(userId)) { 474ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return null; 475ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4765504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 477d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(), 478abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, packageName, id, userId); 4795504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 4805504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 4815504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 482d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki public boolean hasShortcutHostPermission(String callingPackage) { 4832d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 484d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 485d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage); 4862d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 4872d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 4882d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki @Override 48983f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki public boolean startShortcut(String callingPackage, String packageName, String shortcutId, 490abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki Rect sourceBounds, Bundle startActivityOptions, int userId) { 491d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki verifyCallingPackage(callingPackage); 4923a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, userId, "Cannot start activity"); 493d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki 494abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (!isUserEnabled(userId)) { 495ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot start a shortcut for disabled profile " 496abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki + userId); 497ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 498ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 499d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki // Even without the permission, pinned shortcuts are always launchable. 500d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), 501abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, packageName, shortcutId, userId)) { 502abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki ensureShortcutPermission(callingPackage, userId); 503d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki } 5046f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 505440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki final Intent[] intents = mShortcutServiceInternal.createShortcutIntents( 506440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki getCallingUserId(), callingPackage, packageName, shortcutId, userId); 507440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki if (intents == null || intents.length == 0) { 50883f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return false; 50943204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 51043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki // Note the target activity doesn't have to be exported. 51143204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki 5127e5c3e85420a255bd79242dd97b90340c6e3a4dfMakoto Onuki intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5130eed441c0cf3bd03b8ac780e62fbeae5d7fcac4bMakoto Onuki intents[0].setSourceBounds(sourceBounds); 514440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki 515440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki return startShortcutIntentsAsPublisher( 516440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki intents, packageName, startActivityOptions, userId); 517ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki } 518ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki 519440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents, 520ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki @NonNull String publisherPackage, Bundle startActivityOptions, int userId) { 52183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki final int code; 52283f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki final long ident = injectClearCallingIdentity(); 52343204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki try { 524440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki code = mActivityManagerInternal.startActivitiesAsPackage(publisherPackage, 525440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki userId, intents, startActivityOptions); 52683f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki if (code >= ActivityManager.START_SUCCESS) { 52783f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return true; // Success 52883f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } else { 52983f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki Log.e(TAG, "Couldn't start activity, code=" + code); 530ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki } 53183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return code >= ActivityManager.START_SUCCESS; 53283f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } catch (SecurityException e) { 53383f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki if (DEBUG) { 53483f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki Slog.d(TAG, "SecurityException while launching intent", e); 53583f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } 53683f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return false; 53783f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } finally { 53883f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki injectRestoreCallingIdentity(ident); 53943204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 5406f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 5416f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 542772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 5433a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public boolean isActivityEnabled( 5443a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, ComponentName component, UserHandle user) 545df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 5463a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage , user, "Cannot check component"); 547df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 548df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 549932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 550df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 551932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani long ident = Binder.clearCallingIdentity(); 552932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani try { 553df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IPackageManager pm = AppGlobals.getPackageManager(); 554cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey ActivityInfo info = pm.getActivityInfo(component, 5558a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5568a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 5578a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 558dcf21d15456e5aca28d063aea73139e30842e6d1Winson Chung return info != null; 559932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } finally { 560932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani Binder.restoreCallingIdentity(ident); 561932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 562932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 563932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani 5644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 5653a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public void startActivityAsUser(String callingPackage, 5663a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ComponentName component, Rect sourceBounds, 567df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Bundle opts, UserHandle user) throws RemoteException { 5683a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, user, "Cannot start activity"); 569df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 570df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throw new IllegalStateException("Cannot start activity for disabled profile " + user); 5714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 5724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 573df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Intent launchIntent = new Intent(Intent.ACTION_MAIN); 574df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); 575347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki launchIntent.setSourceBounds(sourceBounds); 576347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 577347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 5782df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setPackage(component.getPackageName()); 579df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 580df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 581df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 5822df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy IPackageManager pm = AppGlobals.getPackageManager(); 583cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey ActivityInfo info = pm.getActivityInfo(component, 5848a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5858a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 5868a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 5872df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (!info.exported) { 5882df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Cannot launch non-exported components " 5892df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + component); 5902df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 5912df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy 5922df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Check that the component actually has Intent.CATEGORY_LAUCNCHER 5932df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // as calling startActivityAsUser ignores the category and just 5942df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // resolves based on the component if present. 5952df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent, 5968a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5978a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 5988a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 5992df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy final int size = apps.size(); 6002df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy for (int i = 0; i < size; ++i) { 6012df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy ActivityInfo activityInfo = apps.get(i).activityInfo; 6022df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (activityInfo.packageName.equals(component.getPackageName()) && 6032df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy activityInfo.name.equals(component.getClassName())) { 6042df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Found an activity with category launcher that matches 6052df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // this component so ok to launch. 6062df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setComponent(component); 6072df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy mContext.startActivityAsUser(launchIntent, opts, user); 6082df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy return; 6092df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 6102df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 6112df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Attempt to launch activity without " 6122df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + " category Intent.CATEGORY_LAUNCHER " + component); 613df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 614df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 615df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 618466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy @Override 6193a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public void showAppDetailsAsUser(String callingPackage, ComponentName component, 6203a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { 6213a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ensureInUserProfiles(callingPackage, user, "Cannot show app details"); 622466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy if (!isUserEnabled(user)) { 623466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy throw new IllegalStateException("Cannot show app details for disabled profile " 624466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy + user); 625466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 626466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 627466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy long ident = Binder.clearCallingIdentity(); 628466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy try { 629466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy String packageName = component.getPackageName(); 630466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, 631466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Uri.fromParts("package", packageName, null)); 632369aad0e23a1ca1417018c540730915760fe2ed3Winson intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 633466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy intent.setSourceBounds(sourceBounds); 634466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy mContext.startActivityAsUser(intent, opts, user); 635466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } finally { 636466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Binder.restoreCallingIdentity(ident); 637466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 638466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 639466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 6404dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki /** Checks if user is a profile of or same as listeningUser. 6414dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki * and the user is enabled. */ 642ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, 6434dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki String debugMsg) { 6444dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (user.getIdentifier() == listeningUser.getIdentifier()) { 6454dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg); 6464dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 6474dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 648ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 6494dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki try { 6504dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo userInfo = mUm.getUserInfo(user.getIdentifier()); 6514dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); 6524dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (userInfo == null || listeningUserInfo == null 6534dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 6544dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId != listeningUserInfo.profileGroupId 6554dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || !userInfo.isEnabled()) { 6564dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 6574dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":" 6584dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 659df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6604dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return false; 6614dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } else { 6624dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 6634dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":" 6644dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 6654dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 6664dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 6674f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6684dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } finally { 669ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 6704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6714dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 6724dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 673c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki @VisibleForTesting 674aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki void postToPackageMonitorHandler(Runnable r) { 675c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mCallbackHandler.post(r); 6764dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 6774dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 6784dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener { 6794f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 6806f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki // TODO Simplify with lambdas. 6816f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 682df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 683df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageAdded(String packageName, int uid) { 684df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 685df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 6867bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 6877bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 6887bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 6897bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 6907bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageAdded")) continue; 6917bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 6927bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageAdded(user, packageName); 6937bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 6947bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 6957bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 696df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6977bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 6987bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 6994f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 700df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 701df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageAdded(packageName, uid); 7024f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 704df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 705df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageRemoved(String packageName, int uid) { 706df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 707df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7087bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7097bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7107bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7117bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7127bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageRemoved")) continue; 7137bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7147bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageRemoved(user, packageName); 7157bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7167bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7177bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 718df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7197bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7207bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 721df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7224f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 723df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageRemoved(packageName, uid); 724df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 725df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 726df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 727df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageModified(String packageName) { 728df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 729df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7307bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7317bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7327bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7337bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7347bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageModified")) continue; 7357bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7367bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageChanged(user, packageName); 7377bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7387bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7397bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 740df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7417bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7427bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 7434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 744df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 745df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageModified(packageName); 7464f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7474f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 748df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 749df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesAvailable(String[] packages) { 750df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 751df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7527bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7537bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7547bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7557bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7567bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesAvailable")) continue; 7577bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7587bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesAvailable(user, packages, isReplacing()); 7597bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7607bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7617bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 762df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7637bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7647bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 765df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 767df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesAvailable(packages); 768df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 769df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 770df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 771df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesUnavailable(String[] packages) { 772df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 773df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7747bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7757bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7767bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7777bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7787bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnavailable")) continue; 7797bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7807bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesUnavailable(user, packages, isReplacing()); 7817bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7827bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7837bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 784df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7857bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7867bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 7874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 788df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 789df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesUnavailable(packages); 7904f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7914f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 792772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 793772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesSuspended(String[] packages) { 794772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 795772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 7967bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7977bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7987bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7997bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8007bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesSuspended")) continue; 8017bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8027bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesSuspended(user, packages); 8037bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8047bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8057bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 806772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 8077bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8087bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 809772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 810772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 811772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesSuspended(packages); 812772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 813772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 814772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 815772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesUnsuspended(String[] packages) { 816772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 817772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 8187bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8197bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8207bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8217bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8227bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnsuspended")) continue; 8237bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8247bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesUnsuspended(user, packages); 8257bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8267bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8277bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 828772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 8297bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8307bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 831772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 832772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 833772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesUnsuspended(packages); 834772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 835772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 8366f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 8376f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void onShortcutChanged(@NonNull String packageName, 8384dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 839aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId)); 8404dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 8414dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 8424dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private void onShortcutChangedInner(@NonNull String packageName, 8434dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 8447bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki final int n = mListeners.beginBroadcast(); 84502f338e23d06499790c6948709afb1587416eb40Makoto Onuki try { 84602f338e23d06499790c6948709afb1587416eb40Makoto Onuki final UserHandle user = UserHandle.of(userId); 84702f338e23d06499790c6948709afb1587416eb40Makoto Onuki 84802f338e23d06499790c6948709afb1587416eb40Makoto Onuki for (int i = 0; i < n; i++) { 84902f338e23d06499790c6948709afb1587416eb40Makoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 85002f338e23d06499790c6948709afb1587416eb40Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 85102f338e23d06499790c6948709afb1587416eb40Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue; 85202f338e23d06499790c6948709afb1587416eb40Makoto Onuki 85302f338e23d06499790c6948709afb1587416eb40Makoto Onuki final int launcherUserId = cookie.user.getIdentifier(); 85402f338e23d06499790c6948709afb1587416eb40Makoto Onuki 85502f338e23d06499790c6948709afb1587416eb40Makoto Onuki // Make sure the caller has the permission. 85602f338e23d06499790c6948709afb1587416eb40Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission( 85702f338e23d06499790c6948709afb1587416eb40Makoto Onuki launcherUserId, cookie.packageName)) { 85802f338e23d06499790c6948709afb1587416eb40Makoto Onuki continue; 85902f338e23d06499790c6948709afb1587416eb40Makoto Onuki } 86002f338e23d06499790c6948709afb1587416eb40Makoto Onuki // Each launcher has a different set of pinned shortcuts, so we need to do a 86102f338e23d06499790c6948709afb1587416eb40Makoto Onuki // query in here. 86202f338e23d06499790c6948709afb1587416eb40Makoto Onuki // (As of now, only one launcher has the permission at a time, so it's bit 86302f338e23d06499790c6948709afb1587416eb40Makoto Onuki // moot, but we may change the permission model eventually.) 86402f338e23d06499790c6948709afb1587416eb40Makoto Onuki final List<ShortcutInfo> list = 86502f338e23d06499790c6948709afb1587416eb40Makoto Onuki mShortcutServiceInternal.getShortcuts(launcherUserId, 86602f338e23d06499790c6948709afb1587416eb40Makoto Onuki cookie.packageName, 86702f338e23d06499790c6948709afb1587416eb40Makoto Onuki /* changedSince= */ 0, packageName, /* shortcutIds=*/ null, 86802f338e23d06499790c6948709afb1587416eb40Makoto Onuki /* component= */ null, 86902f338e23d06499790c6948709afb1587416eb40Makoto Onuki ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY 87002f338e23d06499790c6948709afb1587416eb40Makoto Onuki | ShortcutQuery.FLAG_GET_ALL_KINDS 87102f338e23d06499790c6948709afb1587416eb40Makoto Onuki , userId); 87202f338e23d06499790c6948709afb1587416eb40Makoto Onuki try { 87302f338e23d06499790c6948709afb1587416eb40Makoto Onuki listener.onShortcutChanged(user, packageName, 87402f338e23d06499790c6948709afb1587416eb40Makoto Onuki new ParceledListSlice<>(list)); 87502f338e23d06499790c6948709afb1587416eb40Makoto Onuki } catch (RemoteException re) { 87602f338e23d06499790c6948709afb1587416eb40Makoto Onuki Slog.d(TAG, "Callback failed ", re); 87702f338e23d06499790c6948709afb1587416eb40Makoto Onuki } 8786f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 87902f338e23d06499790c6948709afb1587416eb40Makoto Onuki } catch (RuntimeException e) { 88002f338e23d06499790c6948709afb1587416eb40Makoto Onuki // When the user is locked we get IllegalState, so just catch all. 88102f338e23d06499790c6948709afb1587416eb40Makoto Onuki Log.w(TAG, e.getMessage(), e); 8827bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8837bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 8846f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 8856f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 8864f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 8874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 888df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> { 889df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 890df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onCallbackDied(T callback, Object cookie) { 891df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani checkCallbackCount(); 892df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 8934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 8944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 895b6830197450d5a2befaf0dc4f7e73850f4c55846Nicolas Prevot} 896