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; 3718211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedyimport android.content.pm.PackageManagerInternal; 386f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.PackageManager.NameNotFoundException; 396cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyalimport android.content.pm.ParceledListSlice; 404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.ResolveInfo; 416f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutInfo; 426f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutServiceInternal; 436f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; 444f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.UserInfo; 454f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.graphics.Rect; 46466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guyimport android.net.Uri; 474f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Binder; 484f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Bundle; 49c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onukiimport android.os.Handler; 504f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.IInterface; 515504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onukiimport android.os.ParcelFileDescriptor; 524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteCallbackList; 534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteException; 544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserHandle; 554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserManager; 56466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guyimport android.provider.Settings; 57932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasaniimport android.util.Log; 584f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.util.Slog; 594f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 607a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onukiimport com.android.internal.annotations.VisibleForTesting; 614f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport com.android.internal.content.PackageMonitor; 62c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onukiimport com.android.internal.os.BackgroundThread; 636f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport com.android.internal.util.Preconditions; 646f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport com.android.server.LocalServices; 65df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasaniimport com.android.server.SystemService; 664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 67ac21497f174504472e92b99500709518b8ab2d71Makoto Onukiimport java.util.ArrayList; 68de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onukiimport java.util.Collections; 694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.List; 704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/** 724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Service that manages requests and callbacks for launchers that support 736f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki * managed profiles. 744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */ 75df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasanipublic class LauncherAppsService extends SystemService { 76df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 77df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final LauncherAppsImpl mLauncherAppsImpl; 784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 794f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani public LauncherAppsService(Context context) { 80df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super(context); 81df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mLauncherAppsImpl = new LauncherAppsImpl(context); 824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 844f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 85df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onStart() { 86df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl); 87df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 88df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 894dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki static class BroadcastCookie { 904dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public final UserHandle user; 914dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public final String packageName; 924dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 934dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie(UserHandle userHandle, String packageName) { 944dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki this.user = userHandle; 954dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki this.packageName = packageName; 964dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 974dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 984dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 997a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting 1006f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki static class LauncherAppsImpl extends ILauncherApps.Stub { 101df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private static final boolean DEBUG = false; 102df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private static final String TAG = "LauncherAppsService"; 103df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final Context mContext; 104df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final UserManager mUm; 105ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki private final ActivityManagerInternal mActivityManagerInternal; 1066f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki private final ShortcutServiceInternal mShortcutServiceInternal; 107df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final PackageCallbackList<IOnAppsChangedListener> mListeners 108df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani = new PackageCallbackList<IOnAppsChangedListener>(); 109df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 1106f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor(); 111df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 112c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki private final Handler mCallbackHandler; 113c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki 114df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public LauncherAppsImpl(Context context) { 115df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mContext = context; 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 219de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki /** See {@link #canAccessProfile(String, int, String)} */ 220de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki private boolean canAccessProfile( 221de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki String callingPackage, UserHandle targetUser, String message) { 222de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return canAccessProfile(callingPackage, targetUser.getIdentifier(), message); 223abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 224abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 225de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki /** 226de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * Checks if the calling user is in the same group as {@code targetUser}, and allowed 227de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * to access it. 228de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * 229de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * @return TRUE if the calling user can access {@code targetUserId}. FALSE if not *but 230de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * they're still in the same profile group*. 231de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * 232de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * @throws SecurityException if the calling user and {@code targetUser} are not in the same 233de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * group. 234de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki */ 235de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki private boolean canAccessProfile(String callingPackage, int targetUserId, String message) { 236ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki final int callingUserId = injectCallingUserId(); 237cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 238de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (targetUserId == callingUserId) return true; 2394f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 240ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 241df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 242df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); 243aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki if (callingUserInfo.isManagedProfile()) { 2443cc7cd1c18f5d5b2df0f8aebb22fdb3feb23ecd0Makoto Onuki Slog.w(TAG, message + " by " + callingPackage + " for another profile " 2453a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki + targetUserId + " from " + callingUserId); 246de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 247aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki } 248aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki 249df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); 250df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (targetUserInfo == null 251df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 252df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { 253aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki throw new SecurityException(message + " for unrelated profile " + targetUserId); 254df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 255df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 256ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 257df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 258de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return true; 259cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina } 2604f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 2617a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting // We override it in unit tests 2627a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki void verifyCallingPackage(String callingPackage) { 2636f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki int packageUid = -1; 2646f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki try { 26518211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy packageUid = AppGlobals.getPackageManager().getPackageUid(callingPackage, 2668a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 2678a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE 2683ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki | PackageManager.MATCH_UNINSTALLED_PACKAGES, 2693ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki UserHandle.getUserId(getCallingUid())); 27018211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy } catch (RemoteException ignore) { 27118211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy } 27218211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy if (packageUid < 0) { 2736f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki Log.e(TAG, "Package not found: " + callingPackage); 2746f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 27518211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy if (packageUid != injectBinderCallingUid()) { 2766f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki throw new SecurityException("Calling package name mismatch"); 2776f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2786f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2796f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 280df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 281df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Checks if the user is enabled. 282df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 283df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private boolean isUserEnabled(UserHandle user) { 284abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki return isUserEnabled(user.getIdentifier()); 285abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 286abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 287abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki private boolean isUserEnabled(int userId) { 288ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 289df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 290abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki UserInfo targetUserInfo = mUm.getUserInfo(userId); 291df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return targetUserInfo != null && targetUserInfo.isEnabled(); 292df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 293ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 294df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 2954f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2964f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 297df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 2983a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage, 2993a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String packageName, UserHandle user) 300df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 3013a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki return queryActivitiesForUser(callingPackage, 302a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal new Intent(Intent.ACTION_MAIN) 303a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal .addCategory(Intent.CATEGORY_LAUNCHER) 304a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal .setPackage(packageName), 305a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal user); 306a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 307a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 308a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal @Override 3093a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ActivityInfo resolveActivity( 3103a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, ComponentName component, UserHandle user) 311a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal throws RemoteException { 312de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot resolve activity")) { 313de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 314de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 315df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 3166cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal return null; 317df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 318cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 31918211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final int callingUid = injectBinderCallingUid(); 320df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 321df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 32218211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final PackageManagerInternal pmInt = 32318211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy LocalServices.getService(PackageManagerInternal.class); 32418211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy return pmInt.getActivityInfo(component, 3258a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3268a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 32718211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy callingUid, user.getIdentifier()); 328df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 329df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 330df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 33153fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 33253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 333df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 3343a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ParceledListSlice getShortcutConfigActivities( 3353a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, String packageName, UserHandle user) 336df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 3373a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki return queryActivitiesForUser(callingPackage, 338a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName), user); 339a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 340a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 3413a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage, 3423a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki Intent intent, UserHandle user) { 343de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot retrieve activities")) { 344de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 345de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 346df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 347df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return null; 348df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 349cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 35018211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final int callingUid = injectBinderCallingUid(); 351a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal long ident = injectClearCallingIdentity(); 352df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 35318211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final PackageManagerInternal pmInt = 35418211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy LocalServices.getService(PackageManagerInternal.class); 35518211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy List<ResolveInfo> apps = pmInt.queryIntentActivities(intent, 3568a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3578a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 35818211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy callingUid, user.getIdentifier()); 359a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return new ParceledListSlice<>(apps); 360df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 361a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal injectRestoreCallingIdentity(ident); 362a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 363a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 364a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 365a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal @Override 366a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal public IntentSender getShortcutConfigActivityIntent(String callingPackage, 367a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal ComponentName component, UserHandle user) throws RemoteException { 368de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 369de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot check package")) { 370de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 371de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 372a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Preconditions.checkNotNull(component); 373a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Preconditions.checkArgument(isUserEnabled(user), "User not enabled"); 374a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 375a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal // All right, create the sender. 376a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component); 377a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal final long identity = Binder.clearCallingIdentity(); 378a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal try { 379de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki final PendingIntent pi = PendingIntent.getActivityAsUser( 380a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT 381a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT, 382de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki null, user); 383de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return pi == null ? null : pi.getIntentSender(); 384a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } finally { 385a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Binder.restoreCallingIdentity(identity); 386df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 38753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 38853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 389df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 3903a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user) 391df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 392de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot check package")) { 393de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 394de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 395df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 396df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 397df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 3984f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 39918211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final int callingUid = injectBinderCallingUid(); 400df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 401df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 40218211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final PackageManagerInternal pmInt = 40318211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy LocalServices.getService(PackageManagerInternal.class); 40418211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy PackageInfo info = pmInt.getPackageInfo(packageName, 4058a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 4068a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 40718211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy callingUid, user.getIdentifier()); 408df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return info != null && info.applicationInfo.enabled; 409df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 410df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 411df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 4124f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 4134f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 414df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 4153a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ApplicationInfo getApplicationInfo( 4163a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, String packageName, int flags, UserHandle user) 417772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy throws RemoteException { 418de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot check package")) { 419de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 420de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 421772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy if (!isUserEnabled(user)) { 422772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return null; 423772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 424772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 42518211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final int callingUid = injectBinderCallingUid(); 426772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy long ident = Binder.clearCallingIdentity(); 427772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy try { 42818211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final PackageManagerInternal pmInt = 42918211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy LocalServices.getService(PackageManagerInternal.class); 43018211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy ApplicationInfo info = pmInt.getApplicationInfo(packageName, flags, 43118211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy callingUid, user.getIdentifier()); 432772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return info; 433772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } finally { 434772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy Binder.restoreCallingIdentity(ident); 435772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 436772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 437772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 438de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki private void ensureShortcutPermission(@NonNull String callingPackage) { 4392d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 440d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 441d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage)) { 4422d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki throw new SecurityException("Caller can't access shortcut information"); 4432d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 4446f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4456f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4466f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4476f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public ParceledListSlice getShortcuts(String callingPackage, long changedSince, 44899302b55c6a960c9078ad2c84ae9be3296bd32f3Makoto Onuki String packageName, List shortcutIds, ComponentName componentName, int flags, 44999302b55c6a960c9078ad2c84ae9be3296bd32f3Makoto Onuki UserHandle targetUser) { 450de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 451de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUser, "Cannot get shortcuts") 452de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki || !isUserEnabled(targetUser)) { 453de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return new ParceledListSlice<>(Collections.EMPTY_LIST); 454ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 455abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (shortcutIds != null && packageName == null) { 456abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki throw new IllegalArgumentException( 457abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki "To query by shortcut ID, package name must also be set"); 458abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 4596f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 460f93ce176dec4691165c78bf25fe36fbf3a93a096Felipe Leme // TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below. 461f93ce176dec4691165c78bf25fe36fbf3a93a096Felipe Leme return new ParceledListSlice<>((List<ShortcutInfo>) 462d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.getShortcuts(getCallingUserId(), 463abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, changedSince, packageName, shortcutIds, 46499302b55c6a960c9078ad2c84ae9be3296bd32f3Makoto Onuki componentName, flags, targetUser.getIdentifier())); 4656f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4666f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4676f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4686f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void pinShortcuts(String callingPackage, String packageName, List<String> ids, 469de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki UserHandle targetUser) { 470de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 471de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUser, "Cannot pin shortcuts")) { 472de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return; 473de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 474de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!isUserEnabled(targetUser)) { 475ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot pin shortcuts for disabled profile " 476de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki + targetUser); 477ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4786f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 479d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.pinShortcuts(getCallingUserId(), 480de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki callingPackage, packageName, ids, targetUser.getIdentifier()); 4816f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4826f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4836f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 484abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki public int getShortcutIconResId(String callingPackage, String packageName, String id, 485de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki int targetUserId) { 486de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 487de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { 488de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return 0; 489de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 490de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!isUserEnabled(targetUserId)) { 491ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return 0; 492ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4935504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 494d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(), 495de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki callingPackage, packageName, id, targetUserId); 4965504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 4975504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 4985504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 499abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki public ParcelFileDescriptor getShortcutIconFd(String callingPackage, 500de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki String packageName, String id, int targetUserId) { 501de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 502de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { 503de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 504de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 505de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!isUserEnabled(targetUserId)) { 506ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return null; 507ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 5085504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 509d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(), 510de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki callingPackage, packageName, id, targetUserId); 5115504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 5125504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 5135504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 514d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki public boolean hasShortcutHostPermission(String callingPackage) { 5152d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 516d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 517d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage); 5182d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 5192d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 5202d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki @Override 52183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki public boolean startShortcut(String callingPackage, String packageName, String shortcutId, 522de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { 523d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki verifyCallingPackage(callingPackage); 524de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUserId, "Cannot start activity")) { 525de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 526de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 527de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!isUserEnabled(targetUserId)) { 528ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot start a shortcut for disabled profile " 529de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki + targetUserId); 530ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 531ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 532d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki // Even without the permission, pinned shortcuts are always launchable. 533d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), 534de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki callingPackage, packageName, shortcutId, targetUserId)) { 535de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 536d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki } 5376f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 538440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki final Intent[] intents = mShortcutServiceInternal.createShortcutIntents( 539de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId); 540440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki if (intents == null || intents.length == 0) { 54183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return false; 54243204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 54343204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki // Note the target activity doesn't have to be exported. 54443204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki 5457e5c3e85420a255bd79242dd97b90340c6e3a4dfMakoto Onuki intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5460eed441c0cf3bd03b8ac780e62fbeae5d7fcac4bMakoto Onuki intents[0].setSourceBounds(sourceBounds); 547440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki 548440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki return startShortcutIntentsAsPublisher( 549de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki intents, packageName, startActivityOptions, targetUserId); 550ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki } 551ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki 552440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents, 553ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki @NonNull String publisherPackage, Bundle startActivityOptions, int userId) { 55483f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki final int code; 55583f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki final long ident = injectClearCallingIdentity(); 55643204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki try { 557440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki code = mActivityManagerInternal.startActivitiesAsPackage(publisherPackage, 558440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki userId, intents, startActivityOptions); 5597f9368637c8d2726b87cbe184b240512055da037Bryce Lee if (ActivityManager.isStartResultSuccessful(code)) { 56083f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return true; // Success 56183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } else { 56283f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki Log.e(TAG, "Couldn't start activity, code=" + code); 563ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki } 5647f9368637c8d2726b87cbe184b240512055da037Bryce Lee return false; 56583f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } catch (SecurityException e) { 56683f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki if (DEBUG) { 56783f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki Slog.d(TAG, "SecurityException while launching intent", e); 56883f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } 56983f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return false; 57083f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } finally { 57183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki injectRestoreCallingIdentity(ident); 57243204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 5736f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 5746f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 575772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 5763a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public boolean isActivityEnabled( 5773a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, ComponentName component, UserHandle user) 578df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 579de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage , user, "Cannot check component")) { 580de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 581de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 582df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 583df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 584932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 585df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 58618211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final int callingUid = injectBinderCallingUid(); 587932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani long ident = Binder.clearCallingIdentity(); 588932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani try { 58918211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final PackageManagerInternal pmInt = 59018211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy LocalServices.getService(PackageManagerInternal.class); 59118211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy ActivityInfo info = pmInt.getActivityInfo(component, 5928a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5938a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 59418211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy callingUid, user.getIdentifier()); 595dcf21d15456e5aca28d063aea73139e30842e6d1Winson Chung return info != null; 596932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } finally { 597932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani Binder.restoreCallingIdentity(ident); 598932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 599932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 600932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani 6014f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 6023a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public void startActivityAsUser(String callingPackage, 6033a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ComponentName component, Rect sourceBounds, 604df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Bundle opts, UserHandle user) throws RemoteException { 605de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot start activity")) { 606de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return; 607de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 608df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 609df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throw new IllegalStateException("Cannot start activity for disabled profile " + user); 6104f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6114f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 612df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Intent launchIntent = new Intent(Intent.ACTION_MAIN); 613df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); 614347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki launchIntent.setSourceBounds(sourceBounds); 615347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 616347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 6172df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setPackage(component.getPackageName()); 618df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 61918211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final int callingUid = injectBinderCallingUid(); 620df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 621df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 62218211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy final PackageManagerInternal pmInt = 62318211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy LocalServices.getService(PackageManagerInternal.class); 62418211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy ActivityInfo info = pmInt.getActivityInfo(component, 6258a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 6268a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 62718211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy callingUid, user.getIdentifier()); 6282df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (!info.exported) { 6292df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Cannot launch non-exported components " 6302df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + component); 6312df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 6322df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy 6332df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Check that the component actually has Intent.CATEGORY_LAUCNCHER 6342df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // as calling startActivityAsUser ignores the category and just 6352df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // resolves based on the component if present. 63618211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent, 6378a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 6388a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 63918211fd8f6ff4a70a4b8b16fab642783d536102bTodd Kennedy callingUid, user.getIdentifier()); 6402df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy final int size = apps.size(); 6412df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy for (int i = 0; i < size; ++i) { 6422df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy ActivityInfo activityInfo = apps.get(i).activityInfo; 6432df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (activityInfo.packageName.equals(component.getPackageName()) && 6442df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy activityInfo.name.equals(component.getClassName())) { 6452df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Found an activity with category launcher that matches 6462df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // this component so ok to launch. 6472df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setComponent(component); 6482df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy mContext.startActivityAsUser(launchIntent, opts, user); 6492df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy return; 6502df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 6512df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 6522df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Attempt to launch activity without " 6532df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + " category Intent.CATEGORY_LAUNCHER " + component); 654df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 655df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 656df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6584f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 659466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy @Override 6603a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public void showAppDetailsAsUser(String callingPackage, ComponentName component, 6613a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { 662de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot show app details")) { 663de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return; 664de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 665466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy if (!isUserEnabled(user)) { 666466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy throw new IllegalStateException("Cannot show app details for disabled profile " 667466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy + user); 668466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 669466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 670466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy long ident = Binder.clearCallingIdentity(); 671466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy try { 672466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy String packageName = component.getPackageName(); 673466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, 674466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Uri.fromParts("package", packageName, null)); 675369aad0e23a1ca1417018c540730915760fe2ed3Winson intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 676466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy intent.setSourceBounds(sourceBounds); 677466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy mContext.startActivityAsUser(intent, opts, user); 678466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } finally { 679466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Binder.restoreCallingIdentity(ident); 680466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 681466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 682466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 6834dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki /** Checks if user is a profile of or same as listeningUser. 6844dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki * and the user is enabled. */ 685ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, 6864dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki String debugMsg) { 6874dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (user.getIdentifier() == listeningUser.getIdentifier()) { 688de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (DEBUG) Log.d(TAG, "Delivering msg to same user: " + debugMsg); 6894dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 6904dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 691de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (mUm.isManagedProfile(listeningUser.getIdentifier())) { 692de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (DEBUG) Log.d(TAG, "Managed profile can't see other profiles: " + debugMsg); 693de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 694de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 695ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 6964dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki try { 6974dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo userInfo = mUm.getUserInfo(user.getIdentifier()); 6984dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); 6994dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (userInfo == null || listeningUserInfo == null 7004dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 7014dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId != listeningUserInfo.profileGroupId 7024dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || !userInfo.isEnabled()) { 7034dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 7044dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":" 7054dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 706df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7074dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return false; 7084dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } else { 7094dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 7104dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":" 7114dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 7124dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 7134dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 7144f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7154dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } finally { 716ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 7174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7184dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 7194dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 720c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki @VisibleForTesting 721aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki void postToPackageMonitorHandler(Runnable r) { 722c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mCallbackHandler.post(r); 7234dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 7244dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 7254dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener { 7264f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 7276f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki // TODO Simplify with lambdas. 7286f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 729df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 730df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageAdded(String packageName, int uid) { 731df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 732df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7337bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7347bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7357bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7367bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7377bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageAdded")) continue; 7387bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7397bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageAdded(user, packageName); 7407bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7417bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7427bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 743df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7447bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7457bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 7464f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 747df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 748df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageAdded(packageName, uid); 7494f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7504f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 751df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 752df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageRemoved(String packageName, int uid) { 753df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 754df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7557bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7567bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7577bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7587bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7597bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageRemoved")) continue; 7607bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7617bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageRemoved(user, packageName); 7627bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7637bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7647bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 765df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7667bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7677bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 768df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 770df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageRemoved(packageName, uid); 771df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 772df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 773df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 774df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageModified(String packageName) { 775df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 776df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7777bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7787bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7797bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7807bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7817bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageModified")) continue; 7827bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7837bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageChanged(user, packageName); 7847bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7857bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7867bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 787df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7887bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7897bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 7904f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 791df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 792df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageModified(packageName); 7934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 795df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 796df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesAvailable(String[] packages) { 797df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 798df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7997bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8007bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8017bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8027bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8037bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesAvailable")) continue; 8047bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8057bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesAvailable(user, packages, isReplacing()); 8067bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8077bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8087bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 809df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 8107bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8117bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 812df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 8134f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 814df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesAvailable(packages); 815df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 816df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 817df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 818df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesUnavailable(String[] packages) { 819df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 820df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 8217bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8227bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8237bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8247bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8257bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnavailable")) continue; 8267bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8277bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesUnavailable(user, packages, isReplacing()); 8287bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8297bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8307bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 831df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 8327bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8337bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 8344f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 835df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 836df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesUnavailable(packages); 8374f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 8384f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 839772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 840772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesSuspended(String[] packages) { 841772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 842772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 8437bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8447bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8457bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8467bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8477bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesSuspended")) continue; 8487bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8497bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesSuspended(user, packages); 8507bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8517bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8527bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 853772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 8547bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8557bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 856772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 857772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 858772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesSuspended(packages); 859772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 860772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 861772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 862772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesUnsuspended(String[] packages) { 863772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 864772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 8657bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8667bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8677bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8687bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8697bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnsuspended")) continue; 8707bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8717bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesUnsuspended(user, packages); 8727bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8737bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8747bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 875772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 8767bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8777bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 878772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 879772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 880772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesUnsuspended(packages); 881772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 882772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 8836f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 8846f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void onShortcutChanged(@NonNull String packageName, 8854dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 886aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId)); 8874dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 8884dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 8894dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private void onShortcutChangedInner(@NonNull String packageName, 8904dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 8917bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki final int n = mListeners.beginBroadcast(); 89202f338e23d06499790c6948709afb1587416eb40Makoto Onuki try { 89302f338e23d06499790c6948709afb1587416eb40Makoto Onuki final UserHandle user = UserHandle.of(userId); 89402f338e23d06499790c6948709afb1587416eb40Makoto Onuki 89502f338e23d06499790c6948709afb1587416eb40Makoto Onuki for (int i = 0; i < n; i++) { 89602f338e23d06499790c6948709afb1587416eb40Makoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 89702f338e23d06499790c6948709afb1587416eb40Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 89802f338e23d06499790c6948709afb1587416eb40Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue; 89902f338e23d06499790c6948709afb1587416eb40Makoto Onuki 90002f338e23d06499790c6948709afb1587416eb40Makoto Onuki final int launcherUserId = cookie.user.getIdentifier(); 90102f338e23d06499790c6948709afb1587416eb40Makoto Onuki 90202f338e23d06499790c6948709afb1587416eb40Makoto Onuki // Make sure the caller has the permission. 90302f338e23d06499790c6948709afb1587416eb40Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission( 90402f338e23d06499790c6948709afb1587416eb40Makoto Onuki launcherUserId, cookie.packageName)) { 90502f338e23d06499790c6948709afb1587416eb40Makoto Onuki continue; 90602f338e23d06499790c6948709afb1587416eb40Makoto Onuki } 90702f338e23d06499790c6948709afb1587416eb40Makoto Onuki // Each launcher has a different set of pinned shortcuts, so we need to do a 90802f338e23d06499790c6948709afb1587416eb40Makoto Onuki // query in here. 90902f338e23d06499790c6948709afb1587416eb40Makoto Onuki // (As of now, only one launcher has the permission at a time, so it's bit 91002f338e23d06499790c6948709afb1587416eb40Makoto Onuki // moot, but we may change the permission model eventually.) 91102f338e23d06499790c6948709afb1587416eb40Makoto Onuki final List<ShortcutInfo> list = 91202f338e23d06499790c6948709afb1587416eb40Makoto Onuki mShortcutServiceInternal.getShortcuts(launcherUserId, 91302f338e23d06499790c6948709afb1587416eb40Makoto Onuki cookie.packageName, 91402f338e23d06499790c6948709afb1587416eb40Makoto Onuki /* changedSince= */ 0, packageName, /* shortcutIds=*/ null, 91502f338e23d06499790c6948709afb1587416eb40Makoto Onuki /* component= */ null, 91602f338e23d06499790c6948709afb1587416eb40Makoto Onuki ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY 91702f338e23d06499790c6948709afb1587416eb40Makoto Onuki | ShortcutQuery.FLAG_GET_ALL_KINDS 91802f338e23d06499790c6948709afb1587416eb40Makoto Onuki , userId); 91902f338e23d06499790c6948709afb1587416eb40Makoto Onuki try { 92002f338e23d06499790c6948709afb1587416eb40Makoto Onuki listener.onShortcutChanged(user, packageName, 92102f338e23d06499790c6948709afb1587416eb40Makoto Onuki new ParceledListSlice<>(list)); 92202f338e23d06499790c6948709afb1587416eb40Makoto Onuki } catch (RemoteException re) { 92302f338e23d06499790c6948709afb1587416eb40Makoto Onuki Slog.d(TAG, "Callback failed ", re); 92402f338e23d06499790c6948709afb1587416eb40Makoto Onuki } 9256f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 92602f338e23d06499790c6948709afb1587416eb40Makoto Onuki } catch (RuntimeException e) { 92702f338e23d06499790c6948709afb1587416eb40Makoto Onuki // When the user is locked we get IllegalState, so just catch all. 92802f338e23d06499790c6948709afb1587416eb40Makoto Onuki Log.w(TAG, e.getMessage(), e); 9297bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 9307bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 9316f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 9326f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 9334f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 9344f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 935df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> { 936df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 937df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onCallbackDied(T callback, Object cookie) { 938df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani checkCallbackCount(); 939df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 9404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 9414f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 942b6830197450d5a2befaf0dc4f7e73850f4c55846Nicolas Prevot} 943