LauncherAppsService.java revision ac21497f174504472e92b99500709518b8ab2d71
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; 2043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onukiimport android.annotation.Nullable; 216f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.annotation.UserIdInt; 2253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.app.AppGlobals; 234f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.ComponentName; 244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.Context; 254f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.Intent; 2653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.ActivityInfo; 27772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guyimport android.content.pm.ApplicationInfo; 284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.ILauncherApps; 294f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.IOnAppsChangedListener; 3053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.IPackageManager; 314dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onukiimport android.content.pm.LauncherApps.ShortcutQuery; 3253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.PackageInfo; 33cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkeyimport android.content.pm.PackageManager; 346f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.PackageManager.NameNotFoundException; 356cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyalimport android.content.pm.ParceledListSlice; 364f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.ResolveInfo; 376f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutInfo; 386f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutServiceInternal; 396f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; 404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.UserInfo; 414f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.graphics.Rect; 42466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guyimport android.net.Uri; 434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Binder; 444f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Bundle; 45c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onukiimport android.os.Handler; 464f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.IInterface; 475504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onukiimport android.os.ParcelFileDescriptor; 484f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteCallbackList; 494f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteException; 504f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserHandle; 514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserManager; 52466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guyimport android.provider.Settings; 53932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasaniimport android.util.Log; 544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.util.Slog; 554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 567a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onukiimport com.android.internal.annotations.VisibleForTesting; 574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport com.android.internal.content.PackageMonitor; 58c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onukiimport com.android.internal.os.BackgroundThread; 596f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport com.android.internal.util.Preconditions; 606f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport com.android.server.LocalServices; 61df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasaniimport com.android.server.SystemService; 624f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 63ac21497f174504472e92b99500709518b8ab2d71Makoto Onukiimport java.util.ArrayList; 644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.List; 654f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/** 674f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Service that manages requests and callbacks for launchers that support 686f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki * managed profiles. 694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */ 70df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasanipublic class LauncherAppsService extends SystemService { 71df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 72df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final LauncherAppsImpl mLauncherAppsImpl; 734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani public LauncherAppsService(Context context) { 75df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super(context); 76df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mLauncherAppsImpl = new LauncherAppsImpl(context); 774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 794f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 80df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onStart() { 814dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Binder.LOG_RUNTIME_EXCEPTION = true; 82df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl); 83df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 84df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 854dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki static class BroadcastCookie { 864dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public final UserHandle user; 874dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public final String packageName; 884dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 894dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie(UserHandle userHandle, String packageName) { 904dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki this.user = userHandle; 914dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki this.packageName = packageName; 924dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 934dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 944dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 957a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting 966f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki static class LauncherAppsImpl extends ILauncherApps.Stub { 97df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private static final boolean DEBUG = false; 98df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private static final String TAG = "LauncherAppsService"; 99df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final Context mContext; 100df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final PackageManager mPm; 101df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final UserManager mUm; 1026f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki private final ShortcutServiceInternal mShortcutServiceInternal; 103df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private final PackageCallbackList<IOnAppsChangedListener> mListeners 104df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani = new PackageCallbackList<IOnAppsChangedListener>(); 105df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 1066f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor(); 107df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 108c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki private final Handler mCallbackHandler; 109c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki 110df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public LauncherAppsImpl(Context context) { 111df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mContext = context; 112df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mPm = mContext.getPackageManager(); 113df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 1146f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki mShortcutServiceInternal = Preconditions.checkNotNull( 1156f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki LocalServices.getService(ShortcutServiceInternal.class)); 1166f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki mShortcutServiceInternal.addListener(mPackageMonitor); 117c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mCallbackHandler = BackgroundThread.getHandler(); 118df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 119df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 1202d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki @VisibleForTesting 1212d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki int injectBinderCallingUid() { 1222d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki return getCallingUid(); 1232d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 1242d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 125ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki final int injectCallingUserId() { 126ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return UserHandle.getUserId(injectBinderCallingUid()); 127ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 128ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 129ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki @VisibleForTesting 130ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long injectClearCallingIdentity() { 131ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return Binder.clearCallingIdentity(); 132ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 133ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 134ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki // Injection point. 135ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki @VisibleForTesting 136ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki void injectRestoreCallingIdentity(long token) { 137ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki Binder.restoreCallingIdentity(token); 138ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 139ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 1402d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki private int getCallingUserId() { 1412d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki return UserHandle.getUserId(injectBinderCallingUid()); 1422d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 1432d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 144df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /* 145df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * @see android.content.pm.ILauncherApps#addOnAppsChangedListener( 146df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * android.content.pm.IOnAppsChangedListener) 147df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 148df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 1494dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener) 1504dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki throws RemoteException { 151df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 152932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani if (DEBUG) { 153df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle()); 154932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 155df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 156df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 157df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Starting package monitoring"); 158df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 159df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani startWatchingPackageBroadcasts(); 160df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 161df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.unregister(listener); 1624dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki mListeners.register(listener, new BroadcastCookie(UserHandle.of(getCallingUserId()), 1634dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki callingPackage)); 1644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1654f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 167df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /* 168df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener( 169df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * android.content.pm.IOnAppsChangedListener) 170df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 171df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 172df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void removeOnAppsChangedListener(IOnAppsChangedListener listener) 173df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 174df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 175df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 176df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Removing listener from " + Binder.getCallingUserHandle()); 177df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 178df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.unregister(listener); 179df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 180df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani stopWatchingPackageBroadcasts(); 181df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 1824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 1844f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 185df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 186df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Register a receiver to watch for package broadcasts 187df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 188df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private void startWatchingPackageBroadcasts() { 189c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mPackageMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler); 190932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 1914f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 192df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 193df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Unregister package broadcast receiver 194df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 195df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private void stopWatchingPackageBroadcasts() { 196932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani if (DEBUG) { 197df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Stopped watching for packages"); 1984f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 199df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mPackageMonitor.unregister(); 2004f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2014f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 202df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani void checkCallbackCount() { 203df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani synchronized (mListeners) { 204df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (DEBUG) { 205df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Log.d(TAG, "Callback count = " + mListeners.getRegisteredCallbackCount()); 206df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 207df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (mListeners.getRegisteredCallbackCount() == 0) { 208df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani stopWatchingPackageBroadcasts(); 209df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 2104f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2114f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2124f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 213df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 214df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Checks if the caller is in the same group as the userToCheck. 215df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 216ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki private void ensureInUserProfiles(UserHandle userToCheck, String message) { 217ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki final int callingUserId = injectCallingUserId(); 218df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int targetUserId = userToCheck.getIdentifier(); 219cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 220df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (targetUserId == callingUserId) return; 2214f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 222ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 223df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 224df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); 225df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); 226df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (targetUserInfo == null 227df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 228df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) { 229df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throw new SecurityException(message); 230df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 231df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 232ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 233df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 234cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina } 2354f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 2367a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki @VisibleForTesting // We override it in unit tests 2377a6a05f0ccc8c57496d0a1e2b0882ab7de3175e5Makoto Onuki void verifyCallingPackage(String callingPackage) { 2386f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki int packageUid = -1; 2396f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki try { 2403ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki packageUid = mPm.getPackageUidAsUser(callingPackage, 2418a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 2428a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE 2433ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki | PackageManager.MATCH_UNINSTALLED_PACKAGES, 2443ee7f71d5f1dc018fdafee9d890290909ad299dfMakoto Onuki UserHandle.getUserId(getCallingUid())); 2456f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } catch (NameNotFoundException e) { 2466f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki Log.e(TAG, "Package not found: " + callingPackage); 2476f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2486f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki if (packageUid != Binder.getCallingUid()) { 2496f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki throw new SecurityException("Calling package name mismatch"); 2506f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2516f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 2526f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 253df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani /** 254df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani * Checks if the user is enabled. 255df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani */ 256df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani private boolean isUserEnabled(UserHandle user) { 257ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 258df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 259df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserInfo targetUserInfo = mUm.getUserInfo(user.getIdentifier()); 260df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return targetUserInfo != null && targetUserInfo.isEnabled(); 261df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 262ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 263df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 2644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 2654f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 266df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 2676cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal public ParceledListSlice<ResolveInfo> getLauncherActivities(String packageName, UserHandle user) 268df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 269df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani ensureInUserProfiles(user, "Cannot retrieve activities for unrelated profile " + user); 270df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 2716cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal return null; 272df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 273cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 274df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 275df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 276df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mainIntent.setPackage(packageName); 277df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 278df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 279cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent, 2808a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 2818a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 2828a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 2836cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal return new ParceledListSlice<>(apps); 284df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 285df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 286df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 28753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 28853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 289df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 290df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public ResolveInfo resolveActivity(Intent intent, UserHandle user) 291df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 292df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani ensureInUserProfiles(user, "Cannot resolve activity for unrelated profile " + user); 293df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 294df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return null; 295df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 296cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina 297df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 298df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 299cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey ResolveInfo app = mPm.resolveActivityAsUser(intent, 3008a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3018a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3028a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 303df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return app; 304df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 305df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 306df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 30753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy } 30853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy 309df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 310df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public boolean isPackageEnabled(String packageName, UserHandle user) 311df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 312df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user); 313df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 314df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 315df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 3164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 317df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 318df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 319df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IPackageManager pm = AppGlobals.getPackageManager(); 320cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey PackageInfo info = pm.getPackageInfo(packageName, 3218a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 3228a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 3238a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 324df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return info != null && info.applicationInfo.enabled; 325df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 326df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 327df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 3284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 3294f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 330df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 331772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) 332772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy throws RemoteException { 333772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user); 334772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy if (!isUserEnabled(user)) { 335772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return null; 336772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 337772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 338772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy long ident = Binder.clearCallingIdentity(); 339772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy try { 340772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy IPackageManager pm = AppGlobals.getPackageManager(); 341772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy ApplicationInfo info = pm.getApplicationInfo(packageName, flags, 342772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy user.getIdentifier()); 343772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy return info; 344772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } finally { 345772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy Binder.restoreCallingIdentity(ident); 346772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 347772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 348772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 3492d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki private void ensureShortcutPermission(@NonNull String callingPackage, UserHandle user) { 3502d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 3516f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user); 3522d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 353d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 354d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage)) { 3552d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki throw new SecurityException("Caller can't access shortcut information"); 3562d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 3576f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 3586f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 3596f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 3606f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public ParceledListSlice getShortcuts(String callingPackage, long changedSince, 361d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki String packageName, ComponentName componentName, int flags, UserHandle user) { 3622d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 363ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 364ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return new ParceledListSlice<>(new ArrayList(0)); 365ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 3666f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 3676f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki return new ParceledListSlice<>( 368d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.getShortcuts(getCallingUserId(), 369d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, changedSince, packageName, 370d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki componentName, flags, user.getIdentifier())); 3716f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 3726f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 3736f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 3746f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public ParceledListSlice getShortcutInfo(String callingPackage, String packageName, 375d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki List<String> ids, UserHandle user) { 3762d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 377ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 378ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return new ParceledListSlice<>(new ArrayList(0)); 379ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 3806f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 3816f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki return new ParceledListSlice<>( 382d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.getShortcutInfo(getCallingUserId(), 383d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, packageName, ids, user.getIdentifier())); 3846f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 3856f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 3866f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 3876f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void pinShortcuts(String callingPackage, String packageName, List<String> ids, 388d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki UserHandle user) { 3892d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 390ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 391ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot pin shortcuts for disabled profile " 392ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki + user); 393ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 3946f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 395d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.pinShortcuts(getCallingUserId(), 396d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, packageName, ids, user.getIdentifier()); 3976f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 3986f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 3996f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 4005504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki public int getShortcutIconResId(String callingPackage, ShortcutInfo shortcut, 4015504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki UserHandle user) { 4022d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 403ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 404ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return 0; 405ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4065504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 407d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(), 408d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, shortcut, user.getIdentifier()); 4095504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 4105504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 4115504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 4125504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki public ParcelFileDescriptor getShortcutIconFd(String callingPackage, ShortcutInfo shortcut, 4135504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki UserHandle user) { 4142d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki ensureShortcutPermission(callingPackage, user); 415ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 416ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki return null; 417ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 4185504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 419d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(), 420d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, shortcut, user.getIdentifier()); 4215504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki } 4225504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki 4235504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki @Override 424d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki public boolean hasShortcutHostPermission(String callingPackage) { 4252d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki verifyCallingPackage(callingPackage); 426d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), 427d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage); 4282d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki } 4292d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 4302d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki @Override 43143204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki public boolean startShortcut(String callingPackage, String packageName, String shortcutId, 432d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki Rect sourceBounds, Bundle startActivityOptions, UserHandle user) { 433d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki verifyCallingPackage(callingPackage); 434d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user); 435d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki 436ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki if (!isUserEnabled(user)) { 437ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki throw new IllegalStateException("Cannot start a shortcut for disabled profile " 438ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki + user); 439ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki } 440ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki 441d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki // Even without the permission, pinned shortcuts are always launchable. 442d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), 443d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, packageName, shortcutId, user.getIdentifier())) { 444d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki ensureShortcutPermission(callingPackage, user); 445d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki } 4466f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 447d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki final Intent intent = mShortcutServiceInternal.createShortcutIntent(getCallingUserId(), 448d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki callingPackage, packageName, shortcutId, user.getIdentifier()); 44943204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki if (intent == null) { 45043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki return false; 45143204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 45243204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki // Note the target activity doesn't have to be exported. 45343204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki 45443204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki intent.setSourceBounds(sourceBounds); 45543204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki prepareIntentForLaunch(intent, sourceBounds); 45643204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki 45743204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki final long ident = Binder.clearCallingIdentity(); 45843204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki try { 45943204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki mContext.startActivityAsUser(intent, startActivityOptions, user); 46043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } finally { 46143204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki Binder.restoreCallingIdentity(ident); 46243204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 46343204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki return true; 4646f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 4656f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 466772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 467df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public boolean isActivityEnabled(ComponentName component, UserHandle user) 468df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throws RemoteException { 469df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani ensureInUserProfiles(user, "Cannot check component for unrelated profile " + user); 470df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 471df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani return false; 472932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 473df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 474932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani long ident = Binder.clearCallingIdentity(); 475932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani try { 476df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IPackageManager pm = AppGlobals.getPackageManager(); 477cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey ActivityInfo info = pm.getActivityInfo(component, 4788a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 4798a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 4808a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 481dcf21d15456e5aca28d063aea73139e30842e6d1Winson Chung return info != null; 482932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } finally { 483932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani Binder.restoreCallingIdentity(ident); 484932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 485932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani } 486932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani 4874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani @Override 488df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void startActivityAsUser(ComponentName component, Rect sourceBounds, 489df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Bundle opts, UserHandle user) throws RemoteException { 490df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user); 491df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani if (!isUserEnabled(user)) { 492df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani throw new IllegalStateException("Cannot start activity for disabled profile " + user); 4934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 4944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 495df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Intent launchIntent = new Intent(Intent.ACTION_MAIN); 496df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); 49743204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki prepareIntentForLaunch(launchIntent, sourceBounds); 4982df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setPackage(component.getPackageName()); 499df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 500df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani long ident = Binder.clearCallingIdentity(); 501df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 5022df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy IPackageManager pm = AppGlobals.getPackageManager(); 503cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey ActivityInfo info = pm.getActivityInfo(component, 5048a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5058a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 5068a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 5072df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (!info.exported) { 5082df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Cannot launch non-exported components " 5092df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + component); 5102df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 5112df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy 5122df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Check that the component actually has Intent.CATEGORY_LAUCNCHER 5132df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // as calling startActivityAsUser ignores the category and just 5142df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // resolves based on the component if present. 5152df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent, 5168a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.MATCH_DIRECT_BOOT_AWARE 5178a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 5188a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey user.getIdentifier()); 5192df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy final int size = apps.size(); 5202df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy for (int i = 0; i < size; ++i) { 5212df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy ActivityInfo activityInfo = apps.get(i).activityInfo; 5222df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy if (activityInfo.packageName.equals(component.getPackageName()) && 5232df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy activityInfo.name.equals(component.getClassName())) { 5242df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // Found an activity with category launcher that matches 5252df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy // this component so ok to launch. 5262df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy launchIntent.setComponent(component); 5272df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy mContext.startActivityAsUser(launchIntent, opts, user); 5282df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy return; 5292df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 5302df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy } 5312df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy throw new SecurityException("Attempt to launch activity without " 5322df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy + " category Intent.CATEGORY_LAUNCHER " + component); 533df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } finally { 534df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Binder.restoreCallingIdentity(ident); 535df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 5364f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 5374f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 53843204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki private void prepareIntentForLaunch(@NonNull Intent launchIntent, 53943204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki @Nullable Rect sourceBounds) { 54043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki launchIntent.setSourceBounds(sourceBounds); 54143204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 54243204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 54343204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki } 54443204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki 545466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy @Override 546466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy public void showAppDetailsAsUser(ComponentName component, Rect sourceBounds, 547466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Bundle opts, UserHandle user) throws RemoteException { 548466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy ensureInUserProfiles(user, "Cannot show app details for unrelated profile " + user); 549466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy if (!isUserEnabled(user)) { 550466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy throw new IllegalStateException("Cannot show app details for disabled profile " 551466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy + user); 552466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 553466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 554466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy long ident = Binder.clearCallingIdentity(); 555466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy try { 556466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy String packageName = component.getPackageName(); 557466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, 558466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Uri.fromParts("package", packageName, null)); 559369aad0e23a1ca1417018c540730915760fe2ed3Winson intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 560466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy intent.setSourceBounds(sourceBounds); 561466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy mContext.startActivityAsUser(intent, opts, user); 562466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } finally { 563466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy Binder.restoreCallingIdentity(ident); 564466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 565466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy } 566466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy 5674dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki /** Checks if user is a profile of or same as listeningUser. 5684dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki * and the user is enabled. */ 569ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, 5704dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki String debugMsg) { 5714dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (user.getIdentifier() == listeningUser.getIdentifier()) { 5724dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg); 5734dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 5744dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 575ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki long ident = injectClearCallingIdentity(); 5764dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki try { 5774dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo userInfo = mUm.getUserInfo(user.getIdentifier()); 5784dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); 5794dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (userInfo == null || listeningUserInfo == null 5804dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID 5814dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || userInfo.profileGroupId != listeningUserInfo.profileGroupId 5824dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki || !userInfo.isEnabled()) { 5834dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 5844dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":" 5854dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 586df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 5874dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return false; 5884dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } else { 5894dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (DEBUG) { 5904dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":" 5914dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki + debugMsg); 5924dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 5934dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki return true; 5944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 5954dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } finally { 596ac21497f174504472e92b99500709518b8ab2d71Makoto Onuki injectRestoreCallingIdentity(ident); 5974f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 5984dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 5994dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 600c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki @VisibleForTesting 601aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki void postToPackageMonitorHandler(Runnable r) { 602c5475d42a45ba48477257879e7a5b2af54a23f98Makoto Onuki mCallbackHandler.post(r); 6034dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 6044dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 6054dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener { 6064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 6076f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki // TODO Simplify with lambdas. 6086f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 609df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 610df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageAdded(String packageName, int uid) { 611df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 612df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 613df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani for (int i = 0; i < n; i++) { 614df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 6154dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 6164dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageAdded")) continue; 617df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 618df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani listener.onPackageAdded(user, packageName); 619df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } catch (RemoteException re) { 620df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Slog.d(TAG, "Callback failed ", re); 621df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6224f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 623df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.finishBroadcast(); 624df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 625df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageAdded(packageName, uid); 6264f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6274f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 628df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 629df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageRemoved(String packageName, int uid) { 630df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 631df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 632df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani for (int i = 0; i < n; i++) { 633df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 6344dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 6354dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageRemoved")) continue; 636df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 637df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani listener.onPackageRemoved(user, packageName); 638df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } catch (RemoteException re) { 639df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Slog.d(TAG, "Callback failed ", re); 640df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 641df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 642df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.finishBroadcast(); 6434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 644df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageRemoved(packageName, uid); 645df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 646df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 647df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 648df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackageModified(String packageName) { 649df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 650df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 651df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani for (int i = 0; i < n; i++) { 652df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 6534dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 6544dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackageModified")) continue; 655df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 656df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani listener.onPackageChanged(user, packageName); 657df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } catch (RemoteException re) { 658df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Slog.d(TAG, "Callback failed ", re); 659df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6604f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 661df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.finishBroadcast(); 662df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 663df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackageModified(packageName); 6644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 6654f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 666df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 667df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesAvailable(String[] packages) { 668df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 669df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 670df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani for (int i = 0; i < n; i++) { 671df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 6724dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 6734dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesAvailable")) continue; 674df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 675df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani listener.onPackagesAvailable(user, packages, isReplacing()); 676df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } catch (RemoteException re) { 677df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Slog.d(TAG, "Callback failed ", re); 678df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 679df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 680df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.finishBroadcast(); 6814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 682df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesAvailable(packages); 683df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 684df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 685df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 686df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onPackagesUnavailable(String[] packages) { 687df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani UserHandle user = new UserHandle(getChangingUserId()); 688df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani final int n = mListeners.beginBroadcast(); 689df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani for (int i = 0; i < n; i++) { 690df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 6914dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 6924dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnavailable")) continue; 693df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani try { 694df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani listener.onPackagesUnavailable(user, packages, isReplacing()); 695df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } catch (RemoteException re) { 696df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani Slog.d(TAG, "Callback failed ", re); 697df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 6984f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 699df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani mListeners.finishBroadcast(); 700df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani 701df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani super.onPackagesUnavailable(packages); 7024f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 704772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 705772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesSuspended(String[] packages) { 706772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 707772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 708772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy for (int i = 0; i < n; i++) { 709772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7104dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7114dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesSuspended")) continue; 712772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy try { 713772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy listener.onPackagesSuspended(user, packages); 714772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } catch (RemoteException re) { 715772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy Slog.d(TAG, "Callback failed ", re); 716772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 717772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 718772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy mListeners.finishBroadcast(); 719772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 720772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesSuspended(packages); 721772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 722772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 723772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy @Override 724772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy public void onPackagesUnsuspended(String[] packages) { 725772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy UserHandle user = new UserHandle(getChangingUserId()); 726772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy final int n = mListeners.beginBroadcast(); 727772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy for (int i = 0; i < n; i++) { 728772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7294dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7304dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onPackagesUnsuspended")) continue; 731772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy try { 732772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy listener.onPackagesUnsuspended(user, packages); 733772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } catch (RemoteException re) { 734772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy Slog.d(TAG, "Callback failed ", re); 735772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 736772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 737772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy mListeners.finishBroadcast(); 738772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 739772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy super.onPackagesUnsuspended(packages); 740772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy } 741772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy 7426f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki @Override 7436f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki public void onShortcutChanged(@NonNull String packageName, 7444dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 745aa8b94aa79df94d77d0f7698ce532ac98f197a99Makoto Onuki postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId)); 7464dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 7474dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki 7484dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki private void onShortcutChangedInner(@NonNull String packageName, 7494dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki @UserIdInt int userId) { 7506f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki final UserHandle user = UserHandle.of(userId); 7516f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki 7526f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki final int n = mListeners.beginBroadcast(); 7536f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki for (int i = 0; i < n; i++) { 7546f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); 7554dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); 7564dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue; 7572d5b465fa9235e66ec176f6d6ffaaa0c18143e41Makoto Onuki 758d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki final int launcherUserId = cookie.user.getIdentifier(); 759d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki 7604dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki // Make sure the caller has the permission. 761d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki if (!mShortcutServiceInternal.hasShortcutHostPermission( 762d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki launcherUserId, cookie.packageName)) { 7634dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki continue; 7644dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki } 7654dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki // Each launcher has a different set of pinned shortcuts, so we need to do a 7664dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki // query in here. 7674dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki // (As of now, only one launcher has the permission at a time, so it's bit 7684dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki // moot, but we may change the permission model eventually.) 7694dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki final List<ShortcutInfo> list = 770d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki mShortcutServiceInternal.getShortcuts(launcherUserId, 771d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki cookie.packageName, 772d99c6f04bbb68f8be78f2c3ca625a3a8d5645275Makoto Onuki /* changedSince= */ 0, packageName, /* component= */ null, 7734dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY 7744dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki | ShortcutQuery.FLAG_GET_PINNED 7754dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki | ShortcutQuery.FLAG_GET_DYNAMIC 7764dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki , userId); 7776f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki try { 7786f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki listener.onShortcutChanged(user, packageName, 7794dbe0ded4ae9faaef580be80184fca0749e27198Makoto Onuki new ParceledListSlice<>(list)); 7806f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } catch (RemoteException re) { 7816f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki Slog.d(TAG, "Callback failed ", re); 7826f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 7836f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 7846f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki mListeners.finishBroadcast(); 7856f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki } 7864f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani 788df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> { 789df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani @Override 790df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani public void onCallbackDied(T callback, Object cookie) { 791df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani checkCallbackCount(); 792df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani } 7934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 7944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani } 795b6830197450d5a2befaf0dc4f7e73850f4c55846Nicolas Prevot} 796