LauncherAppsService.java revision de3c16c8057b61bb3cc2e0c3d5603730f5841c51
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; 67de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onukiimport java.util.Collections; 684f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.List; 694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/** 714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Service that manages requests and callbacks for launchers that support 726f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki * managed profiles. 734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */ 74df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasanipublic class LauncherAppsService extends SystemService { 75df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 76df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final LauncherAppsImpl mLauncherAppsImpl; 774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani public LauncherAppsService(Context context) { 79df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super(context); 80df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mLauncherAppsImpl = new LauncherAppsImpl(context); 814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 84df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onStart() { 85df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl); 86df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 87df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 884dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki static class BroadcastCookie { 894dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public final UserHandle user; 904dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public final String packageName; 914dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 924dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie(UserHandle userHandle, String packageName) { 934dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki this.user = userHandle; 944dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki this.packageName = packageName; 954dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 964dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 974dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 987a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting 996f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki static class LauncherAppsImpl extends ILauncherApps.Stub { 100df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private static final boolean DEBUG = false; 101df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private static final String TAG = "LauncherAppsService"; 102df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final Context mContext; 103df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final PackageManager mPm; 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 mPm = mContext.getPackageManager(); 117df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 118ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki mActivityManagerInternal = Preconditions.checkNotNull( 119ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki LocalServices.getService(ActivityManagerInternal.class)); 1206f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki mShortcutServiceInternal = Preconditions.checkNotNull( 1216f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki LocalServices.getService(ShortcutServiceInternal.class)); 1226f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki mShortcutServiceInternal.addListener(mPackageMonitor); 123c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mCallbackHandler = BackgroundThread.getHandler(); 124df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 125df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 1262d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki @VisibleForTesting 1272d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki int injectBinderCallingUid() { 1282d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki return getCallingUid(); 1292d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 1302d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 131ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki final int injectCallingUserId() { 132ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return UserHandle.getUserId(injectBinderCallingUid()); 133ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 134ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 135ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki @VisibleForTesting 136ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long injectClearCallingIdentity() { 137ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return Binder.clearCallingIdentity(); 138ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 139ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 140ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki // Injection point. 141ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki @VisibleForTesting 142ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki void injectRestoreCallingIdentity(long token) { 143ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki Binder.restoreCallingIdentity(token); 144ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 145ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 1462d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki private int getCallingUserId() { 1472d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki return UserHandle.getUserId(injectBinderCallingUid()); 1482d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 1492d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 150df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /* 151df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * @see android.content.pm.ILauncherApps#addOnAppsChangedListener( 152df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * android.content.pm.IOnAppsChangedListener) 153df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 154df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 1554dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener) 1564dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki throws RemoteException { 1575ba0d3e3a3035b67d2ce3a59975145b1e0061ef4Makoto Onuki verifyCallingPackage(callingPackage); 158df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 159932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani if (DEBUG) { 160df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle()); 161932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 162df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 163df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 164df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Starting package monitoring"); 165df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 166df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani startWatchingPackageBroadcasts(); 167df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 168df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.unregister(listener); 1694dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki mListeners.register(listener, new BroadcastCookie(UserHandle.of(getCallingUserId()), 1704dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki callingPackage)); 1714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 174df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /* 175df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener( 176df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * android.content.pm.IOnAppsChangedListener) 177df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 178df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 179df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void removeOnAppsChangedListener(IOnAppsChangedListener listener) 180df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 181df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 182df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 183df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Removing listener from " + Binder.getCallingUserHandle()); 184df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 185df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.unregister(listener); 186df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 187df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani stopWatchingPackageBroadcasts(); 188df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 1894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1904f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1914f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 192df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 193df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Register a receiver to watch for package broadcasts 194df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 195df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private void startWatchingPackageBroadcasts() { 196c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mPackageMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler); 197932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 1984f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 199df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 200df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Unregister package broadcast receiver 201df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 202df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private void stopWatchingPackageBroadcasts() { 203932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani if (DEBUG) { 204df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Stopped watching for packages"); 2054f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 206df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mPackageMonitor.unregister(); 2074f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2084f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 209df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani void checkCallbackCount() { 210df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 211df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 212df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Callback count = " + mListeners.getRegisteredCallbackCount()); 213df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 214df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 215df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani stopWatchingPackageBroadcasts(); 216df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 2174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2184f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2194f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 220de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki /** See {@link #canAccessProfile(String, int, String)} */ 221de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki private boolean canAccessProfile( 222de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki String callingPackage, UserHandle targetUser, String message) { 223de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return canAccessProfile(callingPackage, targetUser.getIdentifier(), message); 224abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 225abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki 226de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki /** 227de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * Checks if the calling user is in the same group as {@code targetUser}, and allowed 228de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * to access it. 229de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * 230de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * @return TRUE if the calling user can access {@code targetUserId}. FALSE if not *but 231de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * they're still in the same profile group*. 232de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * 233de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * @throws SecurityException if the calling user and {@code targetUser} are not in the same 234de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki * group. 235de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki */ 236de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki private boolean canAccessProfile(String callingPackage, int targetUserId, String message) { 237ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki final int callingUserId = injectCallingUserId(); 238cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 239de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (targetUserId == callingUserId) return true; 2404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 241ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 242df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 243df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); 244aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki if (callingUserInfo.isManagedProfile()) { 2453a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki Slog.wtfStack(TAG, message + " by " + callingPackage + " for another profile " 2463a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki + targetUserId + " from " + callingUserId); 247de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki 248de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 249aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki } 250aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki 251df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); 252df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (targetUserInfo == null 253df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 254df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { 255aecbd037514af1bff0f5ca50932241776d6c5fc3Makoto Onuki throw new SecurityException(message + " for unrelated profile " + targetUserId); 256df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 257df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 258ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 259df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 260de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return true; 261cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina } 2624f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 2637a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting // We override it in unit tests 2647a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki void verifyCallingPackage(String callingPackage) { 2656f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki int packageUid = -1; 2666f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki try { 2673ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki packageUid = mPm.getPackageUidAsUser(callingPackage, 2688a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 2698a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE 2703ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki | PackageManager.MATCH_UNINSTALLED_PACKAGES, 2713ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki UserHandle.getUserId(getCallingUid())); 2726f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } catch (NameNotFoundException e) { 2736f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki Log.e(TAG, "Package not found: " + callingPackage); 2746f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2756f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki if (packageUid != Binder.getCallingUid()) { 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 319df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 320df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 321a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal IPackageManager pm = AppGlobals.getPackageManager(); 322a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return pm.getActivityInfo(component, 3238a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3248a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3258a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 326df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 327df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 328df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 32953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 33053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 331df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 3323a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ParceledListSlice getShortcutConfigActivities( 3333a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, String packageName, UserHandle user) 334df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 3353a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki return queryActivitiesForUser(callingPackage, 336a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName), user); 337a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 338a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 3393a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage, 3403a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki Intent intent, UserHandle user) { 341de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot retrieve activities")) { 342de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 343de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 344df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 345df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return null; 346df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 347cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 348a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal long ident = injectClearCallingIdentity(); 349df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 350a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(intent, 3518a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3528a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3538a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 354a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal return new ParceledListSlice<>(apps); 355df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 356a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal injectRestoreCallingIdentity(ident); 357a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 358a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } 359a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 360a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal @Override 361a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal public IntentSender getShortcutConfigActivityIntent(String callingPackage, 362a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal ComponentName component, UserHandle user) throws RemoteException { 363de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 364de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot check package")) { 365de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 366de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 367a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Preconditions.checkNotNull(component); 368a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Preconditions.checkArgument(isUserEnabled(user), "User not enabled"); 369a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal 370a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal // All right, create the sender. 371a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component); 372a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal final long identity = Binder.clearCallingIdentity(); 373a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal try { 374de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki final PendingIntent pi = PendingIntent.getActivityAsUser( 375a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT 376a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT, 377de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki null, user); 378de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return pi == null ? null : pi.getIntentSender(); 379a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal } finally { 380a6be88a10d6f6391b09f626ead051d0c698fb2d1Sunny Goyal Binder.restoreCallingIdentity(identity); 381df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 38253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 38353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 384df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 3853a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user) 386df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 387de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot check package")) { 388de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 389de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 390df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 391df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 392df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 3934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 394df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 395df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 396df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IPackageManager pm = AppGlobals.getPackageManager(); 397cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey PackageInfo info = pm.getPackageInfo(packageName, 3988a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3998a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 4008a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 401df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return info != null && info.applicationInfo.enabled; 402df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 403df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 404df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 4054f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 4064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 407df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 4083a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public ApplicationInfo getApplicationInfo( 4093a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, String packageName, int flags, UserHandle user) 410772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy throws RemoteException { 411de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot check package")) { 412de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 413de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 414772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy if (!isUserEnabled(user)) { 415772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return null; 416772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 417772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 418772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy long ident = Binder.clearCallingIdentity(); 419772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy try { 420772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy IPackageManager pm = AppGlobals.getPackageManager(); 421772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy ApplicationInfo info = pm.getApplicationInfo(packageName, flags, 422772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy user.getIdentifier()); 423772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return info; 424772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } finally { 425772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy Binder.restoreCallingIdentity(ident); 426772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 427772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 428772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 429de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki private void ensureShortcutPermission(@NonNull String callingPackage) { 4302d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 431d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 432d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage)) { 4332d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki throw new SecurityException("Caller can't access shortcut information"); 4342d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 4356f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4366f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4376f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4386f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public ParceledListSlice getShortcuts(String callingPackage, long changedSince, 439abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki String packageName, List shortcutIds, ComponentName componentName, int flags, 440de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki UserHandle targetUser) { 441de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 442de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUser, "Cannot get shortcuts") 443de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki || !isUserEnabled(targetUser)) { 444de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return new ParceledListSlice<>(Collections.EMPTY_LIST); 445ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 446abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki if (shortcutIds != null && packageName == null) { 447abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki throw new IllegalArgumentException( 448abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki "To query by shortcut ID, package name must also be set"); 449abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki } 4506f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 451f93ce176dec4691165c78bf25fe36fbf3a93a096Felipe Leme // TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below. 452f93ce176dec4691165c78bf25fe36fbf3a93a096Felipe Leme return new ParceledListSlice<>((List<ShortcutInfo>) 453d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.getShortcuts(getCallingUserId(), 454abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki callingPackage, changedSince, packageName, shortcutIds, 455de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki componentName, flags, targetUser.getIdentifier())); 4566f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4576f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4586f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4596f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void pinShortcuts(String callingPackage, String packageName, List<String> ids, 460de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki UserHandle targetUser) { 461de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 462de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUser, "Cannot pin shortcuts")) { 463de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return; 464de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 465de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!isUserEnabled(targetUser)) { 466ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot pin shortcuts for disabled profile " 467de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki + targetUser); 468ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4696f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 470d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.pinShortcuts(getCallingUserId(), 471de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki callingPackage, packageName, ids, targetUser.getIdentifier()); 4726f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4736f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 4746f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 475abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki public int getShortcutIconResId(String callingPackage, String packageName, String id, 476de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki int targetUserId) { 477de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 478de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { 479de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return 0; 480de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 481de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!isUserEnabled(targetUserId)) { 482ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return 0; 483ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4845504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 485d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(), 486de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki callingPackage, packageName, id, targetUserId); 4875504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 4885504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 4895504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 490abe8442951ff88aa01ed882adb54fb1b3472ca3eMakoto Onuki public ParcelFileDescriptor getShortcutIconFd(String callingPackage, 491de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki String packageName, String id, int targetUserId) { 492de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 493de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { 494de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return null; 495de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 496de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!isUserEnabled(targetUserId)) { 497ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return null; 498ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4995504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 500d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(), 501de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki callingPackage, packageName, id, targetUserId); 5025504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 5035504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 5045504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 505d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki public boolean hasShortcutHostPermission(String callingPackage) { 5062d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 507d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 508d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage); 5092d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 5102d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 5112d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki @Override 51283f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki public boolean startShortcut(String callingPackage, String packageName, String shortcutId, 513de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { 514d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki verifyCallingPackage(callingPackage); 515de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUserId, "Cannot start activity")) { 516de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 517de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 518de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) { 519de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 520de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 521de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!isUserEnabled(targetUserId)) { 522ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot start a shortcut for disabled profile " 523de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki + targetUserId); 524ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 525ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 526d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki // Even without the permission, pinned shortcuts are always launchable. 527d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), 528de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki callingPackage, packageName, shortcutId, targetUserId)) { 529de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki ensureShortcutPermission(callingPackage); 530d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki } 5316f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 532440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki final Intent[] intents = mShortcutServiceInternal.createShortcutIntents( 533de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId); 534440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki if (intents == null || intents.length == 0) { 53583f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return false; 53643204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 53743204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki // Note the target activity doesn't have to be exported. 53843204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki 5397e5c3e85420a255bd79242dd97b90340c6e3a4dfMakoto Onuki intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5400eed441c0cf3bd03b8ac780e62fbeae5d7fcac4bMakoto Onuki intents[0].setSourceBounds(sourceBounds); 541440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki 542440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki return startShortcutIntentsAsPublisher( 543de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki intents, packageName, startActivityOptions, targetUserId); 544ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki } 545ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki 546440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents, 547ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki @NonNull String publisherPackage, Bundle startActivityOptions, int userId) { 54883f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki final int code; 54983f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki final long ident = injectClearCallingIdentity(); 55043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki try { 551440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki code = mActivityManagerInternal.startActivitiesAsPackage(publisherPackage, 552440a1ea8e2204ecb171e0187318beb2f08f6012cMakoto Onuki userId, intents, startActivityOptions); 55383f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki if (code >= ActivityManager.START_SUCCESS) { 55483f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return true; // Success 55583f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } else { 55683f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki Log.e(TAG, "Couldn't start activity, code=" + code); 557ea11db15bd0cfe6ecbc44dd80a988ddf0e8c1ce7Makoto Onuki } 55883f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return code >= ActivityManager.START_SUCCESS; 55983f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } catch (SecurityException e) { 56083f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki if (DEBUG) { 56183f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki Slog.d(TAG, "SecurityException while launching intent", e); 56283f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } 56383f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki return false; 56483f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki } finally { 56583f6d2da372de339dc563d6a7786be3facc52e76Makoto Onuki injectRestoreCallingIdentity(ident); 56643204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 5676f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 5686f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 569772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 5703a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public boolean isActivityEnabled( 5713a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki String callingPackage, ComponentName component, UserHandle user) 572df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 573de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage , user, "Cannot check component")) { 574de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 575de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 576df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 577df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 578932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 579df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 580932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani long ident = Binder.clearCallingIdentity(); 581932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani try { 582df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 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()); 587dcf21d15456e5aca28d063aea73139e30842e6d1Winson Chung return info != null; 588932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } finally { 589932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani Binder.restoreCallingIdentity(ident); 590932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 591932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 592932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani 5934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 5943a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public void startActivityAsUser(String callingPackage, 5953a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki ComponentName component, Rect sourceBounds, 596df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Bundle opts, UserHandle user) throws RemoteException { 597de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot start activity")) { 598de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return; 599de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 600df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 601df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throw new IllegalStateException("Cannot start activity for disabled profile " + user); 6024f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 604df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Intent launchIntent = new Intent(Intent.ACTION_MAIN); 605df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); 606347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki launchIntent.setSourceBounds(sourceBounds); 607347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 608347a6bd82059bc7581b1dcd229228f622c5cfca1Makoto Onuki | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 6092df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setPackage(component.getPackageName()); 610df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 611df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 612df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 6132df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy IPackageManager pm = AppGlobals.getPackageManager(); 614cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey ActivityInfo info = pm.getActivityInfo(component, 6158a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 6168a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 6178a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 6182df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (!info.exported) { 6192df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Cannot launch non-exported components " 6202df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + component); 6212df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 6222df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy 6232df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Check that the component actually has Intent.CATEGORY_LAUCNCHER 6242df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // as calling startActivityAsUser ignores the category and just 6252df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // resolves based on the component if present. 6262df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent, 6278a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 6288a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 6298a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 6302df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy final int size = apps.size(); 6312df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy for (int i = 0; i < size; ++i) { 6322df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy ActivityInfo activityInfo = apps.get(i).activityInfo; 6332df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (activityInfo.packageName.equals(component.getPackageName()) && 6342df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy activityInfo.name.equals(component.getClassName())) { 6352df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Found an activity with category launcher that matches 6362df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // this component so ok to launch. 6372df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setComponent(component); 6382df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy mContext.startActivityAsUser(launchIntent, opts, user); 6392df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy return; 6402df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 6412df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 6422df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Attempt to launch activity without " 6432df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + " category Intent.CATEGORY_LAUNCHER " + component); 644df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 645df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 646df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6474f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6484f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 649466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy @Override 6503a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki public void showAppDetailsAsUser(String callingPackage, ComponentName component, 6513a2541e6daec72824f0f9f8c9cd81bacac263b5cMakoto Onuki Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { 652de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (!canAccessProfile(callingPackage, user, "Cannot show app details")) { 653de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return; 654de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 655466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy if (!isUserEnabled(user)) { 656466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy throw new IllegalStateException("Cannot show app details for disabled profile " 657466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy + user); 658466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 659466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 660466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy long ident = Binder.clearCallingIdentity(); 661466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy try { 662466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy String packageName = component.getPackageName(); 663466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, 664466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Uri.fromParts("package", packageName, null)); 665369aad0e23a1ca1417018c540730915760fe2ed3Winson intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 666466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy intent.setSourceBounds(sourceBounds); 667466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy mContext.startActivityAsUser(intent, opts, user); 668466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } finally { 669466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Binder.restoreCallingIdentity(ident); 670466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 671466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 672466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 6734dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki /** Checks if user is a profile of or same as listeningUser. 6744dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki * and the user is enabled. */ 675ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, 6764dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki String debugMsg) { 6774dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (user.getIdentifier() == listeningUser.getIdentifier()) { 678de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (DEBUG) Log.d(TAG, "Delivering msg to same user: " + debugMsg); 6794dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 6804dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 681de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (mUm.isManagedProfile(listeningUser.getIdentifier())) { 682de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki if (DEBUG) Log.d(TAG, "Managed profile can't see other profiles: " + debugMsg); 683de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki return false; 684de3c16c8057b61bb3cc2e0c3d5603730f5841c51Makoto Onuki } 685ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 6864dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki try { 6874dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo userInfo = mUm.getUserInfo(user.getIdentifier()); 6884dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); 6894dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (userInfo == null || listeningUserInfo == null 6904dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 6914dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId != listeningUserInfo.profileGroupId 6924dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || !userInfo.isEnabled()) { 6934dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 6944dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":" 6954dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 696df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6974dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return false; 6984dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } else { 6994dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 7004dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":" 7014dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 7024dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 7034dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 7044f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7054dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } finally { 706ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 7074f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7084dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 7094dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 710c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki @VisibleForTesting 711aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki void postToPackageMonitorHandler(Runnable r) { 712c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mCallbackHandler.post(r); 7134dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 7144dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 7154dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener { 7164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 7176f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki // TODO Simplify with lambdas. 7186f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 719df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 720df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageAdded(String packageName, int uid) { 721df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 722df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7237bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7247bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7257bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7267bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7277bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageAdded")) continue; 7287bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7297bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageAdded(user, packageName); 7307bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7317bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7327bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 733df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7347bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7357bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 7364f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 737df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 738df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageAdded(packageName, uid); 7394f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 741df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 742df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageRemoved(String packageName, int uid) { 743df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 744df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7457bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7467bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7477bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7487bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7497bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageRemoved")) continue; 7507bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7517bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageRemoved(user, packageName); 7527bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7537bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7547bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 755df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7567bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7577bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 758df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7594f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 760df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageRemoved(packageName, uid); 761df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 762df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 763df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 764df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageModified(String packageName) { 765df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 766df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7677bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7687bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7697bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7707bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7717bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageModified")) continue; 7727bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7737bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackageChanged(user, packageName); 7747bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7757bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7767bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 777df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7787bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 7797bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 7804f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 781df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 782df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageModified(packageName); 7834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7844f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 785df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 786df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesAvailable(String[] packages) { 787df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 788df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 7897bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7907bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 7917bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7927bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7937bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesAvailable")) continue; 7947bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 7957bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesAvailable(user, packages, isReplacing()); 7967bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 7977bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7987bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 799df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 8007bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8017bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 802df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 8034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 804df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesAvailable(packages); 805df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 806df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 807df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 808df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesUnavailable(String[] packages) { 809df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 810df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 8117bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8127bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8137bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8147bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8157bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnavailable")) continue; 8167bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8177bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesUnavailable(user, packages, isReplacing()); 8187bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8197bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8207bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 821df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 8227bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8237bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 8244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 825df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 826df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesUnavailable(packages); 8274f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 8284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 829772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 830772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesSuspended(String[] packages) { 831772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 832772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 8337bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8347bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8357bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8367bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8377bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesSuspended")) continue; 8387bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8397bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesSuspended(user, packages); 8407bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8417bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8427bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 843772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 8447bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8457bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 846772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 847772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 848772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesSuspended(packages); 849772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 850772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 851772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 852772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesUnsuspended(String[] packages) { 853772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 854772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 8557bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8567bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki for (int i = 0; i < n; i++) { 8577bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 8587bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 8597bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnsuspended")) continue; 8607bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki try { 8617bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki listener.onPackagesUnsuspended(user, packages); 8627bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } catch (RemoteException re) { 8637bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki Slog.d(TAG, "Callback failed ", re); 8647bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } 865772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 8667bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 8677bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 868772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 869772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 870772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesUnsuspended(packages); 871772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 872772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 8736f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 8746f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void onShortcutChanged(@NonNull String packageName, 8754dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 876aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId)); 8774dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 8784dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 8794dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private void onShortcutChangedInner(@NonNull String packageName, 8804dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 8817bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki final int n = mListeners.beginBroadcast(); 88202f338e23d06499790c6948709afb1587416eb40Makoto Onuki try { 88302f338e23d06499790c6948709afb1587416eb40Makoto Onuki final UserHandle user = UserHandle.of(userId); 88402f338e23d06499790c6948709afb1587416eb40Makoto Onuki 88502f338e23d06499790c6948709afb1587416eb40Makoto Onuki for (int i = 0; i < n; i++) { 88602f338e23d06499790c6948709afb1587416eb40Makoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 88702f338e23d06499790c6948709afb1587416eb40Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 88802f338e23d06499790c6948709afb1587416eb40Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue; 88902f338e23d06499790c6948709afb1587416eb40Makoto Onuki 89002f338e23d06499790c6948709afb1587416eb40Makoto Onuki final int launcherUserId = cookie.user.getIdentifier(); 89102f338e23d06499790c6948709afb1587416eb40Makoto Onuki 89202f338e23d06499790c6948709afb1587416eb40Makoto Onuki // Make sure the caller has the permission. 89302f338e23d06499790c6948709afb1587416eb40Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission( 89402f338e23d06499790c6948709afb1587416eb40Makoto Onuki launcherUserId, cookie.packageName)) { 89502f338e23d06499790c6948709afb1587416eb40Makoto Onuki continue; 89602f338e23d06499790c6948709afb1587416eb40Makoto Onuki } 89702f338e23d06499790c6948709afb1587416eb40Makoto Onuki // Each launcher has a different set of pinned shortcuts, so we need to do a 89802f338e23d06499790c6948709afb1587416eb40Makoto Onuki // query in here. 89902f338e23d06499790c6948709afb1587416eb40Makoto Onuki // (As of now, only one launcher has the permission at a time, so it's bit 90002f338e23d06499790c6948709afb1587416eb40Makoto Onuki // moot, but we may change the permission model eventually.) 90102f338e23d06499790c6948709afb1587416eb40Makoto Onuki final List<ShortcutInfo> list = 90202f338e23d06499790c6948709afb1587416eb40Makoto Onuki mShortcutServiceInternal.getShortcuts(launcherUserId, 90302f338e23d06499790c6948709afb1587416eb40Makoto Onuki cookie.packageName, 90402f338e23d06499790c6948709afb1587416eb40Makoto Onuki /* changedSince= */ 0, packageName, /* shortcutIds=*/ null, 90502f338e23d06499790c6948709afb1587416eb40Makoto Onuki /* component= */ null, 90602f338e23d06499790c6948709afb1587416eb40Makoto Onuki ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY 90702f338e23d06499790c6948709afb1587416eb40Makoto Onuki | ShortcutQuery.FLAG_GET_ALL_KINDS 90802f338e23d06499790c6948709afb1587416eb40Makoto Onuki , userId); 90902f338e23d06499790c6948709afb1587416eb40Makoto Onuki try { 91002f338e23d06499790c6948709afb1587416eb40Makoto Onuki listener.onShortcutChanged(user, packageName, 91102f338e23d06499790c6948709afb1587416eb40Makoto Onuki new ParceledListSlice<>(list)); 91202f338e23d06499790c6948709afb1587416eb40Makoto Onuki } catch (RemoteException re) { 91302f338e23d06499790c6948709afb1587416eb40Makoto Onuki Slog.d(TAG, "Callback failed ", re); 91402f338e23d06499790c6948709afb1587416eb40Makoto Onuki } 9156f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 91602f338e23d06499790c6948709afb1587416eb40Makoto Onuki } catch (RuntimeException e) { 91702f338e23d06499790c6948709afb1587416eb40Makoto Onuki // When the user is locked we get IllegalState, so just catch all. 91802f338e23d06499790c6948709afb1587416eb40Makoto Onuki Log.w(TAG, e.getMessage(), e); 9197bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki } finally { 9207bdb9ce97811782864d3b54616f233c041590c7eMakoto Onuki mListeners.finishBroadcast(); 9216f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 9226f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 9234f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 9244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 925df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> { 926df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 927df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onCallbackDied(T callback, Object cookie) { 928df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani checkCallbackCount(); 929df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 9304f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 9314f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 932b6830197450d5a2befaf0dc4f7e73850f4c55846Nicolas Prevot} 933