blob: b4903817f787dfcde88b157632909ca55477dc9c [file] [log] [blame]
Amith Yamasani4f582632014-02-19 14:31:52 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
Makoto Onuki6f7362d92016-03-04 13:39:41 -080019import android.annotation.NonNull;
20import android.annotation.UserIdInt;
Makoto Onuki83f6d2d2016-07-11 14:30:19 -070021import android.app.ActivityManager;
Makoto Onukiea11db12016-06-24 15:17:44 -070022import android.app.ActivityManagerInternal;
Ricky Waicf134eb2018-10-10 09:26:32 +010023import android.app.AppDetailsActivity;
Kenny Guy53fa4ec2014-04-29 14:24:18 +010024import android.app.AppGlobals;
Makoto Onuki1a342742018-04-26 14:56:59 -070025import android.app.IApplicationThread;
Sunny Goyala6be88a2017-01-12 16:27:58 -080026import android.app.PendingIntent;
Amith Yamasani4f582632014-02-19 14:31:52 -080027import android.content.ComponentName;
28import android.content.Context;
29import android.content.Intent;
Sunny Goyala6be88a2017-01-12 16:27:58 -080030import android.content.IntentSender;
Kenny Guy53fa4ec2014-04-29 14:24:18 +010031import android.content.pm.ActivityInfo;
Kenny Guy77242752016-01-15 13:29:06 +000032import android.content.pm.ApplicationInfo;
Amith Yamasani4f582632014-02-19 14:31:52 -080033import android.content.pm.ILauncherApps;
34import android.content.pm.IOnAppsChangedListener;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -070035import android.content.pm.LauncherApps.ShortcutQuery;
Kenny Guy53fa4ec2014-04-29 14:24:18 +010036import android.content.pm.PackageInfo;
Jeff Sharkeycd654482016-01-08 17:42:11 -070037import android.content.pm.PackageManager;
Todd Kennedy18211fd2017-06-06 09:15:46 -070038import android.content.pm.PackageManagerInternal;
Sunny Goyal6cbc2fe2015-11-24 09:34:20 -080039import android.content.pm.ParceledListSlice;
Amith Yamasani4f582632014-02-19 14:31:52 -080040import android.content.pm.ResolveInfo;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080041import android.content.pm.ShortcutInfo;
42import android.content.pm.ShortcutServiceInternal;
43import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
Makoto Onukie70b29e2018-04-03 16:44:39 -070044import android.content.pm.UserInfo;
Amith Yamasani4f582632014-02-19 14:31:52 -080045import android.graphics.Rect;
Kenny Guy466d2032014-07-23 12:23:35 +010046import android.net.Uri;
Amith Yamasani4f582632014-02-19 14:31:52 -080047import android.os.Binder;
48import android.os.Bundle;
Makoto Onukic5475d42016-03-25 10:54:07 -070049import android.os.Handler;
Amith Yamasani4f582632014-02-19 14:31:52 -080050import android.os.IInterface;
Makoto Onuki55046222016-03-08 10:49:47 -080051import android.os.ParcelFileDescriptor;
Amith Yamasani4f582632014-02-19 14:31:52 -080052import android.os.RemoteCallbackList;
53import android.os.RemoteException;
54import android.os.UserHandle;
Makoto Onukie70b29e2018-04-03 16:44:39 -070055import android.os.UserManager;
Sunny Goyal145c8f82018-02-15 14:27:09 -080056import android.os.UserManagerInternal;
Kenny Guy466d2032014-07-23 12:23:35 +010057import android.provider.Settings;
Amith Yamasani932249d2014-05-01 14:39:35 -070058import android.util.Log;
Amith Yamasani4f582632014-02-19 14:31:52 -080059import android.util.Slog;
60
Makoto Onuki7a6a05f2016-03-10 17:01:08 -080061import com.android.internal.annotations.VisibleForTesting;
Amith Yamasani4f582632014-02-19 14:31:52 -080062import com.android.internal.content.PackageMonitor;
Makoto Onukic5475d42016-03-25 10:54:07 -070063import com.android.internal.os.BackgroundThread;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080064import com.android.internal.util.Preconditions;
65import com.android.server.LocalServices;
Amith Yamasanidf7db072014-06-01 10:41:13 -070066import com.android.server.SystemService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070067import com.android.server.wm.ActivityTaskManagerInternal;
Amith Yamasani4f582632014-02-19 14:31:52 -080068
Ricky Waicf134eb2018-10-10 09:26:32 +010069import java.util.ArrayList;
Makoto Onukide3c16c2017-01-26 11:39:31 -080070import java.util.Collections;
Ricky Waicf134eb2018-10-10 09:26:32 +010071import java.util.HashSet;
Amith Yamasani4f582632014-02-19 14:31:52 -080072import java.util.List;
73
74/**
75 * Service that manages requests and callbacks for launchers that support
Makoto Onuki6f7362d92016-03-04 13:39:41 -080076 * managed profiles.
Amith Yamasani4f582632014-02-19 14:31:52 -080077 */
Amith Yamasanidf7db072014-06-01 10:41:13 -070078public class LauncherAppsService extends SystemService {
79
80 private final LauncherAppsImpl mLauncherAppsImpl;
Amith Yamasani4f582632014-02-19 14:31:52 -080081
82 public LauncherAppsService(Context context) {
Amith Yamasanidf7db072014-06-01 10:41:13 -070083 super(context);
84 mLauncherAppsImpl = new LauncherAppsImpl(context);
Amith Yamasani4f582632014-02-19 14:31:52 -080085 }
86
Amith Yamasani4f582632014-02-19 14:31:52 -080087 @Override
Amith Yamasanidf7db072014-06-01 10:41:13 -070088 public void onStart() {
89 publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl);
90 }
91
Makoto Onuki4dbe0de2016-03-14 17:31:49 -070092 static class BroadcastCookie {
93 public final UserHandle user;
94 public final String packageName;
Makoto Onuki634cecb2017-10-13 17:10:48 -070095 public final int callingUid;
96 public final int callingPid;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -070097
Makoto Onuki634cecb2017-10-13 17:10:48 -070098 BroadcastCookie(UserHandle userHandle, String packageName, int callingPid, int callingUid) {
Makoto Onuki4dbe0de2016-03-14 17:31:49 -070099 this.user = userHandle;
100 this.packageName = packageName;
Makoto Onuki634cecb2017-10-13 17:10:48 -0700101 this.callingUid = callingUid;
102 this.callingPid = callingPid;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700103 }
104 }
105
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800106 @VisibleForTesting
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800107 static class LauncherAppsImpl extends ILauncherApps.Stub {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700108 private static final boolean DEBUG = false;
109 private static final String TAG = "LauncherAppsService";
110 private final Context mContext;
Makoto Onukie70b29e2018-04-03 16:44:39 -0700111 private final UserManager mUm;
Sunny Goyal145c8f82018-02-15 14:27:09 -0800112 private final UserManagerInternal mUserManagerInternal;
Makoto Onukiea11db12016-06-24 15:17:44 -0700113 private final ActivityManagerInternal mActivityManagerInternal;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700114 private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800115 private final ShortcutServiceInternal mShortcutServiceInternal;
Amith Yamasanidf7db072014-06-01 10:41:13 -0700116 private final PackageCallbackList<IOnAppsChangedListener> mListeners
117 = new PackageCallbackList<IOnAppsChangedListener>();
118
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800119 private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700120
Makoto Onukic5475d42016-03-25 10:54:07 -0700121 private final Handler mCallbackHandler;
122
Amith Yamasanidf7db072014-06-01 10:41:13 -0700123 public LauncherAppsImpl(Context context) {
124 mContext = context;
Makoto Onukie70b29e2018-04-03 16:44:39 -0700125 mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800126 mUserManagerInternal = Preconditions.checkNotNull(
127 LocalServices.getService(UserManagerInternal.class));
Makoto Onukiea11db12016-06-24 15:17:44 -0700128 mActivityManagerInternal = Preconditions.checkNotNull(
129 LocalServices.getService(ActivityManagerInternal.class));
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700130 mActivityTaskManagerInternal = Preconditions.checkNotNull(
131 LocalServices.getService(ActivityTaskManagerInternal.class));
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800132 mShortcutServiceInternal = Preconditions.checkNotNull(
133 LocalServices.getService(ShortcutServiceInternal.class));
134 mShortcutServiceInternal.addListener(mPackageMonitor);
Makoto Onukic5475d42016-03-25 10:54:07 -0700135 mCallbackHandler = BackgroundThread.getHandler();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700136 }
137
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800138 @VisibleForTesting
139 int injectBinderCallingUid() {
140 return getCallingUid();
141 }
142
Makoto Onuki634cecb2017-10-13 17:10:48 -0700143 @VisibleForTesting
144 int injectBinderCallingPid() {
145 return getCallingPid();
146 }
147
Makoto Onukiac214972016-04-04 10:19:45 -0700148 final int injectCallingUserId() {
149 return UserHandle.getUserId(injectBinderCallingUid());
150 }
151
152 @VisibleForTesting
153 long injectClearCallingIdentity() {
154 return Binder.clearCallingIdentity();
155 }
156
157 // Injection point.
158 @VisibleForTesting
159 void injectRestoreCallingIdentity(long token) {
160 Binder.restoreCallingIdentity(token);
161 }
162
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800163 private int getCallingUserId() {
164 return UserHandle.getUserId(injectBinderCallingUid());
165 }
166
Amith Yamasanidf7db072014-06-01 10:41:13 -0700167 /*
168 * @see android.content.pm.ILauncherApps#addOnAppsChangedListener(
169 * android.content.pm.IOnAppsChangedListener)
170 */
171 @Override
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700172 public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener)
173 throws RemoteException {
Makoto Onuki5ba0d3e2016-04-11 14:03:46 -0700174 verifyCallingPackage(callingPackage);
Amith Yamasanidf7db072014-06-01 10:41:13 -0700175 synchronized (mListeners) {
Amith Yamasani932249d2014-05-01 14:39:35 -0700176 if (DEBUG) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700177 Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle());
Amith Yamasani932249d2014-05-01 14:39:35 -0700178 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700179 if (mListeners.getRegisteredCallbackCount() == 0) {
180 if (DEBUG) {
181 Log.d(TAG, "Starting package monitoring");
182 }
183 startWatchingPackageBroadcasts();
184 }
185 mListeners.unregister(listener);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700186 mListeners.register(listener, new BroadcastCookie(UserHandle.of(getCallingUserId()),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700187 callingPackage, injectBinderCallingPid(), injectBinderCallingUid()));
Amith Yamasani4f582632014-02-19 14:31:52 -0800188 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800189 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800190
Amith Yamasanidf7db072014-06-01 10:41:13 -0700191 /*
192 * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener(
193 * android.content.pm.IOnAppsChangedListener)
194 */
195 @Override
196 public void removeOnAppsChangedListener(IOnAppsChangedListener listener)
197 throws RemoteException {
198 synchronized (mListeners) {
199 if (DEBUG) {
200 Log.d(TAG, "Removing listener from " + Binder.getCallingUserHandle());
201 }
202 mListeners.unregister(listener);
203 if (mListeners.getRegisteredCallbackCount() == 0) {
204 stopWatchingPackageBroadcasts();
205 }
206 }
207 }
208
209 /**
210 * Register a receiver to watch for package broadcasts
211 */
212 private void startWatchingPackageBroadcasts() {
Makoto Onukic5475d42016-03-25 10:54:07 -0700213 mPackageMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler);
Amith Yamasanidf7db072014-06-01 10:41:13 -0700214 }
215
216 /**
217 * Unregister package broadcast receiver
218 */
219 private void stopWatchingPackageBroadcasts() {
Amith Yamasani932249d2014-05-01 14:39:35 -0700220 if (DEBUG) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700221 Log.d(TAG, "Stopped watching for packages");
Amith Yamasani932249d2014-05-01 14:39:35 -0700222 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700223 mPackageMonitor.unregister();
224 }
225
226 void checkCallbackCount() {
227 synchronized (mListeners) {
228 if (DEBUG) {
229 Log.d(TAG, "Callback count = " + mListeners.getRegisteredCallbackCount());
230 }
231 if (mListeners.getRegisteredCallbackCount() == 0) {
232 stopWatchingPackageBroadcasts();
233 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800234 }
235 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800236
Makoto Onukide3c16c2017-01-26 11:39:31 -0800237 /**
238 * Checks if the calling user is in the same group as {@code targetUser}, and allowed
239 * to access it.
240 *
241 * @return TRUE if the calling user can access {@code targetUserId}. FALSE if not *but
242 * they're still in the same profile group*.
243 *
244 * @throws SecurityException if the calling user and {@code targetUser} are not in the same
245 * group.
246 */
Sunny Goyal145c8f82018-02-15 14:27:09 -0800247 private boolean canAccessProfile(int targetUserId, String message) {
Makoto Onukie70b29e2018-04-03 16:44:39 -0700248 final int callingUserId = injectCallingUserId();
249
250 if (targetUserId == callingUserId) return true;
251
252 long ident = injectClearCallingIdentity();
253 try {
254 final UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
255 if (callingUserInfo != null && callingUserInfo.isManagedProfile()) {
256 Slog.w(TAG, message + " for another profile "
257 + targetUserId + " from " + callingUserId + " not allowed");
258 return false;
259 }
260 } finally {
261 injectRestoreCallingIdentity(ident);
262 }
263
Sunny Goyal145c8f82018-02-15 14:27:09 -0800264 return mUserManagerInternal.isProfileAccessible(injectCallingUserId(), targetUserId,
265 message, true);
Amith Yamasani932249d2014-05-01 14:39:35 -0700266 }
267
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800268 @VisibleForTesting // We override it in unit tests
269 void verifyCallingPackage(String callingPackage) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800270 int packageUid = -1;
271 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700272 packageUid = AppGlobals.getPackageManager().getPackageUid(callingPackage,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600273 PackageManager.MATCH_DIRECT_BOOT_AWARE
274 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
Makoto Onuki3ee7f712016-03-10 17:28:55 -0800275 | PackageManager.MATCH_UNINSTALLED_PACKAGES,
276 UserHandle.getUserId(getCallingUid()));
Todd Kennedy18211fd2017-06-06 09:15:46 -0700277 } catch (RemoteException ignore) {
278 }
279 if (packageUid < 0) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800280 Log.e(TAG, "Package not found: " + callingPackage);
281 }
Todd Kennedy18211fd2017-06-06 09:15:46 -0700282 if (packageUid != injectBinderCallingUid()) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800283 throw new SecurityException("Calling package name mismatch");
284 }
285 }
286
Ricky Waicf134eb2018-10-10 09:26:32 +0100287 private ResolveInfo getHiddenAppActivityInfo(String packageName, int callingUid,
288 UserHandle user) {
289 Intent intent = new Intent();
290 intent.setComponent(new ComponentName(packageName, AppDetailsActivity.class.getName()));
291 final PackageManagerInternal pmInt =
292 LocalServices.getService(PackageManagerInternal.class);
293 List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
294 PackageManager.MATCH_DIRECT_BOOT_AWARE
295 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
296 callingUid, user.getIdentifier());
297 if (apps.size() > 0) {
298 return apps.get(0);
299 }
300 return null;
301 }
302
Amith Yamasani4f582632014-02-19 14:31:52 -0800303 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800304 public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage,
Ricky Waicf134eb2018-10-10 09:26:32 +0100305 String packageName, UserHandle user) throws RemoteException {
306 ParceledListSlice<ResolveInfo> launcherActivities = queryActivitiesForUser(
307 callingPackage,
Sunny Goyala6be88a2017-01-12 16:27:58 -0800308 new Intent(Intent.ACTION_MAIN)
309 .addCategory(Intent.CATEGORY_LAUNCHER)
310 .setPackage(packageName),
311 user);
Ricky Wai13b0abe2018-10-23 11:03:02 +0100312 if (Settings.Global.getInt(mContext.getContentResolver(),
313 Settings.Global.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED, 0) == 0) {
Ricky Waicf134eb2018-10-10 09:26:32 +0100314 return launcherActivities;
315 }
316
317 final int callingUid = injectBinderCallingUid();
318 final ArrayList<ResolveInfo> result = new ArrayList<>(launcherActivities.getList());
Michal Karpinski6d5795f2018-11-06 15:18:30 +0000319 final PackageManagerInternal pmInt =
320 LocalServices.getService(PackageManagerInternal.class);
Ricky Waicf134eb2018-10-10 09:26:32 +0100321 if (packageName != null) {
Michal Karpinski6d5795f2018-11-06 15:18:30 +0000322 // If this hidden app should not be shown, return the original list.
323 // Otherwise, inject hidden activity that forwards user to app details page.
Ricky Waicf134eb2018-10-10 09:26:32 +0100324 if (result.size() > 0) {
325 return launcherActivities;
326 }
Michal Karpinski6d5795f2018-11-06 15:18:30 +0000327 ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName, /*flags*/ 0,
328 callingUid, user.getIdentifier());
329 if (shouldShowHiddenApp(appInfo)) {
330 ResolveInfo info = getHiddenAppActivityInfo(packageName, callingUid, user);
331 if (info != null) {
332 result.add(info);
333 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100334 }
335 return new ParceledListSlice<>(result);
336 }
337
338 long ident = injectClearCallingIdentity();
339 try {
340 final HashSet<String> visiblePackages = new HashSet<>();
341 for (ResolveInfo info : result) {
342 visiblePackages.add(info.activityInfo.packageName);
343 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100344 List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(0,
345 user.getIdentifier(), callingUid);
346 for (ApplicationInfo applicationInfo : installedPackages) {
347 if (!visiblePackages.contains(applicationInfo.packageName)) {
348 if (!shouldShowHiddenApp(applicationInfo)) {
349 continue;
350 }
351 ResolveInfo info = getHiddenAppActivityInfo(applicationInfo.packageName,
352 callingUid, user);
353 if (info != null) {
354 result.add(info);
355 }
356 }
357 }
358 return new ParceledListSlice<>(result);
359 } finally {
360 injectRestoreCallingIdentity(ident);
361 }
362 }
363
364 private static boolean shouldShowHiddenApp(ApplicationInfo appInfo) {
Michal Karpinski08404a952018-11-15 17:46:00 +0000365 if (appInfo == null || appInfo.isSystemApp() || appInfo.isUpdatedSystemApp()) {
Ricky Waicf134eb2018-10-10 09:26:32 +0100366 return false;
367 }
368 return true;
Amith Yamasani4f582632014-02-19 14:31:52 -0800369 }
370
371 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800372 public ActivityInfo resolveActivity(
373 String callingPackage, ComponentName component, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700374 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800375 if (!canAccessProfile(user.getIdentifier(), "Cannot resolve activity")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700376 return null;
Amith Yamasani4f582632014-02-19 14:31:52 -0800377 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800378
Todd Kennedy18211fd2017-06-06 09:15:46 -0700379 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700380 long ident = Binder.clearCallingIdentity();
381 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700382 final PackageManagerInternal pmInt =
383 LocalServices.getService(PackageManagerInternal.class);
384 return pmInt.getActivityInfo(component,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600385 PackageManager.MATCH_DIRECT_BOOT_AWARE
386 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700387 callingUid, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700388 } finally {
389 Binder.restoreCallingIdentity(ident);
390 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800391 }
392
393 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800394 public ParceledListSlice getShortcutConfigActivities(
395 String callingPackage, String packageName, UserHandle user)
Sunny Goyala6be88a2017-01-12 16:27:58 -0800396 throws RemoteException {
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800397 return queryActivitiesForUser(callingPackage,
Sunny Goyala6be88a2017-01-12 16:27:58 -0800398 new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName), user);
399 }
400
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800401 private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage,
402 Intent intent, UserHandle user) {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800403 if (!canAccessProfile(user.getIdentifier(), "Cannot retrieve activities")) {
Sunny Goyala6be88a2017-01-12 16:27:58 -0800404 return null;
405 }
406
Todd Kennedy18211fd2017-06-06 09:15:46 -0700407 final int callingUid = injectBinderCallingUid();
Sunny Goyala6be88a2017-01-12 16:27:58 -0800408 long ident = injectClearCallingIdentity();
409 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700410 final PackageManagerInternal pmInt =
411 LocalServices.getService(PackageManagerInternal.class);
412 List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
Sunny Goyala6be88a2017-01-12 16:27:58 -0800413 PackageManager.MATCH_DIRECT_BOOT_AWARE
414 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700415 callingUid, user.getIdentifier());
Sunny Goyala6be88a2017-01-12 16:27:58 -0800416 return new ParceledListSlice<>(apps);
417 } finally {
418 injectRestoreCallingIdentity(ident);
419 }
420 }
421
422 @Override
423 public IntentSender getShortcutConfigActivityIntent(String callingPackage,
424 ComponentName component, UserHandle user) throws RemoteException {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800425 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800426 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800427 return null;
428 }
Sunny Goyala6be88a2017-01-12 16:27:58 -0800429 Preconditions.checkNotNull(component);
Sunny Goyala6be88a2017-01-12 16:27:58 -0800430
431 // All right, create the sender.
432 Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component);
433 final long identity = Binder.clearCallingIdentity();
434 try {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800435 final PendingIntent pi = PendingIntent.getActivityAsUser(
Sunny Goyala6be88a2017-01-12 16:27:58 -0800436 mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
437 | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800438 null, user);
439 return pi == null ? null : pi.getIntentSender();
Sunny Goyala6be88a2017-01-12 16:27:58 -0800440 } finally {
441 Binder.restoreCallingIdentity(identity);
442 }
443 }
444
445 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800446 public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700447 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800448 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700449 return false;
Amith Yamasani4f582632014-02-19 14:31:52 -0800450 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800451
Todd Kennedy18211fd2017-06-06 09:15:46 -0700452 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700453 long ident = Binder.clearCallingIdentity();
454 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700455 final PackageManagerInternal pmInt =
456 LocalServices.getService(PackageManagerInternal.class);
457 PackageInfo info = pmInt.getPackageInfo(packageName,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600458 PackageManager.MATCH_DIRECT_BOOT_AWARE
459 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700460 callingUid, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700461 return info != null && info.applicationInfo.enabled;
462 } finally {
463 Binder.restoreCallingIdentity(ident);
464 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800465 }
466
467 @Override
Suprabh Shukla19b41f32018-03-26 22:35:13 -0700468 public Bundle getSuspendedPackageLauncherExtras(String packageName,
469 UserHandle user) {
470 if (!canAccessProfile(user.getIdentifier(), "Cannot get launcher extras")) {
471 return null;
472 }
473 final PackageManagerInternal pmi =
474 LocalServices.getService(PackageManagerInternal.class);
475 return pmi.getSuspendedPackageLauncherExtras(packageName, user.getIdentifier());
476 }
477
478 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800479 public ApplicationInfo getApplicationInfo(
480 String callingPackage, String packageName, int flags, UserHandle user)
Kenny Guy77242752016-01-15 13:29:06 +0000481 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800482 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Kenny Guy77242752016-01-15 13:29:06 +0000483 return null;
484 }
485
Todd Kennedy18211fd2017-06-06 09:15:46 -0700486 final int callingUid = injectBinderCallingUid();
Kenny Guy77242752016-01-15 13:29:06 +0000487 long ident = Binder.clearCallingIdentity();
488 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700489 final PackageManagerInternal pmInt =
490 LocalServices.getService(PackageManagerInternal.class);
491 ApplicationInfo info = pmInt.getApplicationInfo(packageName, flags,
492 callingUid, user.getIdentifier());
Kenny Guy77242752016-01-15 13:29:06 +0000493 return info;
494 } finally {
495 Binder.restoreCallingIdentity(ident);
496 }
497 }
498
Makoto Onukide3c16c2017-01-26 11:39:31 -0800499 private void ensureShortcutPermission(@NonNull String callingPackage) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800500 verifyCallingPackage(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700501 if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700502 callingPackage, injectBinderCallingPid(), injectBinderCallingUid())) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800503 throw new SecurityException("Caller can't access shortcut information");
504 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800505 }
506
507 @Override
508 public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
Makoto Onuki99302b52017-03-29 12:42:26 -0700509 String packageName, List shortcutIds, ComponentName componentName, int flags,
510 UserHandle targetUser) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800511 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800512 if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800513 return new ParceledListSlice<>(Collections.EMPTY_LIST);
Makoto Onukiac214972016-04-04 10:19:45 -0700514 }
Makoto Onukiabe84422016-04-07 09:41:19 -0700515 if (shortcutIds != null && packageName == null) {
516 throw new IllegalArgumentException(
517 "To query by shortcut ID, package name must also be set");
518 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800519
Felipe Lemef93ce172016-06-13 14:19:40 -0700520 // TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below.
521 return new ParceledListSlice<>((List<ShortcutInfo>)
Makoto Onukid99c6f02016-03-28 11:02:54 -0700522 mShortcutServiceInternal.getShortcuts(getCallingUserId(),
Makoto Onukiabe84422016-04-07 09:41:19 -0700523 callingPackage, changedSince, packageName, shortcutIds,
Makoto Onuki634cecb2017-10-13 17:10:48 -0700524 componentName, flags, targetUser.getIdentifier(),
525 injectBinderCallingPid(), injectBinderCallingUid()));
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800526 }
527
528 @Override
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800529 public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800530 UserHandle targetUser) {
531 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800532 if (!canAccessProfile(targetUser.getIdentifier(), "Cannot pin shortcuts")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800533 return;
534 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800535
Makoto Onukid99c6f02016-03-28 11:02:54 -0700536 mShortcutServiceInternal.pinShortcuts(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800537 callingPackage, packageName, ids, targetUser.getIdentifier());
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800538 }
539
540 @Override
Makoto Onukiabe84422016-04-07 09:41:19 -0700541 public int getShortcutIconResId(String callingPackage, String packageName, String id,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800542 int targetUserId) {
543 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800544 if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
Makoto Onukiac214972016-04-04 10:19:45 -0700545 return 0;
546 }
Makoto Onuki55046222016-03-08 10:49:47 -0800547
Makoto Onukid99c6f02016-03-28 11:02:54 -0700548 return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800549 callingPackage, packageName, id, targetUserId);
Makoto Onuki55046222016-03-08 10:49:47 -0800550 }
551
552 @Override
Makoto Onukiabe84422016-04-07 09:41:19 -0700553 public ParcelFileDescriptor getShortcutIconFd(String callingPackage,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800554 String packageName, String id, int targetUserId) {
555 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800556 if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
Makoto Onukiac214972016-04-04 10:19:45 -0700557 return null;
558 }
Makoto Onuki55046222016-03-08 10:49:47 -0800559
Makoto Onukid99c6f02016-03-28 11:02:54 -0700560 return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800561 callingPackage, packageName, id, targetUserId);
Makoto Onuki55046222016-03-08 10:49:47 -0800562 }
563
564 @Override
Makoto Onukid99c6f02016-03-28 11:02:54 -0700565 public boolean hasShortcutHostPermission(String callingPackage) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800566 verifyCallingPackage(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700567 return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700568 callingPackage, injectBinderCallingPid(), injectBinderCallingUid());
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800569 }
570
571 @Override
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700572 public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800573 Rect sourceBounds, Bundle startActivityOptions, int targetUserId) {
Makoto Onukid99c6f02016-03-28 11:02:54 -0700574 verifyCallingPackage(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800575 if (!canAccessProfile(targetUserId, "Cannot start activity")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800576 return false;
577 }
Makoto Onukiac214972016-04-04 10:19:45 -0700578
Makoto Onukid99c6f02016-03-28 11:02:54 -0700579 // Even without the permission, pinned shortcuts are always launchable.
580 if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800581 callingPackage, packageName, shortcutId, targetUserId)) {
582 ensureShortcutPermission(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700583 }
584
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700585 final Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
Makoto Onuki634cecb2017-10-13 17:10:48 -0700586 getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId,
587 injectBinderCallingPid(), injectBinderCallingUid());
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700588 if (intents == null || intents.length == 0) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700589 return false;
Makoto Onuki43204b82016-03-08 16:16:44 -0800590 }
591 // Note the target activity doesn't have to be exported.
592
Makoto Onuki7e5c3e82016-07-22 11:57:05 -0700593 intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Makoto Onuki0eed4412016-07-21 11:21:59 -0700594 intents[0].setSourceBounds(sourceBounds);
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700595
596 return startShortcutIntentsAsPublisher(
Makoto Onukide3c16c2017-01-26 11:39:31 -0800597 intents, packageName, startActivityOptions, targetUserId);
Makoto Onukiea11db12016-06-24 15:17:44 -0700598 }
599
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700600 private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents,
Makoto Onukiea11db12016-06-24 15:17:44 -0700601 @NonNull String publisherPackage, Bundle startActivityOptions, int userId) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700602 final int code;
Makoto Onuki43204b82016-03-08 16:16:44 -0800603 try {
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700604 code = mActivityTaskManagerInternal.startActivitiesAsPackage(publisherPackage,
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700605 userId, intents, startActivityOptions);
Bryce Lee7f936862017-05-09 15:33:18 -0700606 if (ActivityManager.isStartResultSuccessful(code)) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700607 return true; // Success
608 } else {
609 Log.e(TAG, "Couldn't start activity, code=" + code);
Makoto Onukiea11db12016-06-24 15:17:44 -0700610 }
Bryce Lee7f936862017-05-09 15:33:18 -0700611 return false;
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700612 } catch (SecurityException e) {
613 if (DEBUG) {
614 Slog.d(TAG, "SecurityException while launching intent", e);
615 }
616 return false;
Makoto Onuki43204b82016-03-08 16:16:44 -0800617 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800618 }
619
Kenny Guy77242752016-01-15 13:29:06 +0000620 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800621 public boolean isActivityEnabled(
622 String callingPackage, ComponentName component, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700623 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800624 if (!canAccessProfile(user.getIdentifier(), "Cannot check component")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700625 return false;
Amith Yamasani4f582632014-02-19 14:31:52 -0800626 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800627
Todd Kennedy18211fd2017-06-06 09:15:46 -0700628 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700629 long ident = Binder.clearCallingIdentity();
630 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700631 final PackageManagerInternal pmInt =
632 LocalServices.getService(PackageManagerInternal.class);
633 ActivityInfo info = pmInt.getActivityInfo(component,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600634 PackageManager.MATCH_DIRECT_BOOT_AWARE
635 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700636 callingUid, user.getIdentifier());
Winson Chungdcf21d152014-10-01 14:30:05 -0700637 return info != null;
Amith Yamasanidf7db072014-06-01 10:41:13 -0700638 } finally {
639 Binder.restoreCallingIdentity(ident);
640 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800641 }
642
Amith Yamasani4f582632014-02-19 14:31:52 -0800643 @Override
Makoto Onuki1a342742018-04-26 14:56:59 -0700644 public void startActivityAsUser(IApplicationThread caller, String callingPackage,
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800645 ComponentName component, Rect sourceBounds,
Amith Yamasanidf7db072014-06-01 10:41:13 -0700646 Bundle opts, UserHandle user) throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800647 if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800648 return;
649 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700650
651 Intent launchIntent = new Intent(Intent.ACTION_MAIN);
652 launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Makoto Onuki347a6bd2016-07-19 11:13:08 -0700653 launchIntent.setSourceBounds(sourceBounds);
654 launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
655 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Kenny Guy2df18922014-07-17 13:01:25 +0100656 launchIntent.setPackage(component.getPackageName());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700657
Makoto Onuki1a342742018-04-26 14:56:59 -0700658 boolean canLaunch = false;
659
Todd Kennedy18211fd2017-06-06 09:15:46 -0700660 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700661 long ident = Binder.clearCallingIdentity();
662 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700663 final PackageManagerInternal pmInt =
664 LocalServices.getService(PackageManagerInternal.class);
Kenny Guy2df18922014-07-17 13:01:25 +0100665 // Check that the component actually has Intent.CATEGORY_LAUCNCHER
666 // as calling startActivityAsUser ignores the category and just
667 // resolves based on the component if present.
Todd Kennedy18211fd2017-06-06 09:15:46 -0700668 List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600669 PackageManager.MATCH_DIRECT_BOOT_AWARE
670 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700671 callingUid, user.getIdentifier());
Kenny Guy2df18922014-07-17 13:01:25 +0100672 final int size = apps.size();
673 for (int i = 0; i < size; ++i) {
674 ActivityInfo activityInfo = apps.get(i).activityInfo;
675 if (activityInfo.packageName.equals(component.getPackageName()) &&
676 activityInfo.name.equals(component.getClassName())) {
Sunny Goyal06ef5af2018-10-16 15:32:41 -0700677 if (!activityInfo.exported) {
678 throw new SecurityException("Cannot launch non-exported components "
679 + component);
680 }
681
Kenny Guy2df18922014-07-17 13:01:25 +0100682 // Found an activity with category launcher that matches
683 // this component so ok to launch.
Tony Mak12917c62018-01-15 15:17:13 +0000684 launchIntent.setPackage(null);
Kenny Guy2df18922014-07-17 13:01:25 +0100685 launchIntent.setComponent(component);
Makoto Onuki1a342742018-04-26 14:56:59 -0700686 canLaunch = true;
687 break;
Kenny Guy2df18922014-07-17 13:01:25 +0100688 }
689 }
Makoto Onuki1a342742018-04-26 14:56:59 -0700690 if (!canLaunch) {
691 throw new SecurityException("Attempt to launch activity without "
692 + " category Intent.CATEGORY_LAUNCHER " + component);
693 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700694 } finally {
695 Binder.restoreCallingIdentity(ident);
696 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700697 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,
Makoto Onuki1a342742018-04-26 14:56:59 -0700698 launchIntent, opts, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700699 }
700
Kenny Guy466d2032014-07-23 12:23:35 +0100701 @Override
Makoto Onuki1a342742018-04-26 14:56:59 -0700702 public void showAppDetailsAsUser(IApplicationThread caller,
703 String callingPackage, ComponentName component,
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800704 Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800705 if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800706 return;
707 }
Kenny Guy466d2032014-07-23 12:23:35 +0100708
Makoto Onuki1a342742018-04-26 14:56:59 -0700709 final Intent intent;
Kenny Guy466d2032014-07-23 12:23:35 +0100710 long ident = Binder.clearCallingIdentity();
711 try {
712 String packageName = component.getPackageName();
Makoto Onuki1a342742018-04-26 14:56:59 -0700713 intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Kenny Guy466d2032014-07-23 12:23:35 +0100714 Uri.fromParts("package", packageName, null));
Winson369aad02016-02-17 10:35:47 -0800715 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Kenny Guy466d2032014-07-23 12:23:35 +0100716 intent.setSourceBounds(sourceBounds);
Kenny Guy466d2032014-07-23 12:23:35 +0100717 } finally {
718 Binder.restoreCallingIdentity(ident);
719 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700720 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,
Makoto Onuki1a342742018-04-26 14:56:59 -0700721 intent, opts, user.getIdentifier());
Kenny Guy466d2032014-07-23 12:23:35 +0100722 }
723
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700724 /** Checks if user is a profile of or same as listeningUser.
725 * and the user is enabled. */
Sunny Goyal145c8f82018-02-15 14:27:09 -0800726 private boolean isEnabledProfileOf(UserHandle listeningUser, UserHandle user,
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700727 String debugMsg) {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800728 return mUserManagerInternal.isProfileAccessible(listeningUser.getIdentifier(),
729 user.getIdentifier(), debugMsg, false);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700730 }
731
Makoto Onukic5475d42016-03-25 10:54:07 -0700732 @VisibleForTesting
Makoto Onukiaa8b94a2016-03-17 13:14:05 -0700733 void postToPackageMonitorHandler(Runnable r) {
Makoto Onukic5475d42016-03-25 10:54:07 -0700734 mCallbackHandler.post(r);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700735 }
736
737 private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700738
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800739 // TODO Simplify with lambdas.
740
Amith Yamasanidf7db072014-06-01 10:41:13 -0700741 @Override
742 public void onPackageAdded(String packageName, int uid) {
743 UserHandle user = new UserHandle(getChangingUserId());
744 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700745 try {
746 for (int i = 0; i < n; i++) {
747 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
748 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800749 if (!isEnabledProfileOf(cookie.user, user, "onPackageAdded")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700750 try {
751 listener.onPackageAdded(user, packageName);
752 } catch (RemoteException re) {
753 Slog.d(TAG, "Callback failed ", re);
754 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700755 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700756 } finally {
757 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700758 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700759
760 super.onPackageAdded(packageName, uid);
761 }
762
763 @Override
764 public void onPackageRemoved(String packageName, int uid) {
765 UserHandle user = new UserHandle(getChangingUserId());
766 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700767 try {
768 for (int i = 0; i < n; i++) {
769 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
770 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800771 if (!isEnabledProfileOf(cookie.user, user, "onPackageRemoved")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700772 try {
773 listener.onPackageRemoved(user, packageName);
774 } catch (RemoteException re) {
775 Slog.d(TAG, "Callback failed ", re);
776 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700777 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700778 } finally {
779 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700780 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700781
782 super.onPackageRemoved(packageName, uid);
783 }
784
785 @Override
786 public void onPackageModified(String packageName) {
787 UserHandle user = new UserHandle(getChangingUserId());
788 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700789 try {
790 for (int i = 0; i < n; i++) {
791 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
792 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800793 if (!isEnabledProfileOf(cookie.user, user, "onPackageModified")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700794 try {
795 listener.onPackageChanged(user, packageName);
796 } catch (RemoteException re) {
797 Slog.d(TAG, "Callback failed ", re);
798 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700799 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700800 } finally {
801 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700802 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700803
804 super.onPackageModified(packageName);
805 }
806
807 @Override
808 public void onPackagesAvailable(String[] packages) {
809 UserHandle user = new UserHandle(getChangingUserId());
810 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700811 try {
812 for (int i = 0; i < n; i++) {
813 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
814 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800815 if (!isEnabledProfileOf(cookie.user, user, "onPackagesAvailable")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700816 try {
817 listener.onPackagesAvailable(user, packages, isReplacing());
818 } catch (RemoteException re) {
819 Slog.d(TAG, "Callback failed ", re);
820 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700821 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700822 } finally {
823 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700824 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700825
826 super.onPackagesAvailable(packages);
827 }
828
829 @Override
830 public void onPackagesUnavailable(String[] packages) {
831 UserHandle user = new UserHandle(getChangingUserId());
832 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700833 try {
834 for (int i = 0; i < n; i++) {
835 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
836 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800837 if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnavailable")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700838 try {
839 listener.onPackagesUnavailable(user, packages, isReplacing());
840 } catch (RemoteException re) {
841 Slog.d(TAG, "Callback failed ", re);
842 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700843 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700844 } finally {
845 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700846 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700847
848 super.onPackagesUnavailable(packages);
849 }
850
Kenny Guy77242752016-01-15 13:29:06 +0000851 @Override
Suprabh Shukla19b41f32018-03-26 22:35:13 -0700852 public void onPackagesSuspended(String[] packages, Bundle launcherExtras) {
Kenny Guy77242752016-01-15 13:29:06 +0000853 UserHandle user = new UserHandle(getChangingUserId());
854 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700855 try {
856 for (int i = 0; i < n; i++) {
857 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
858 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800859 if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700860 try {
Suprabh Shukla19b41f32018-03-26 22:35:13 -0700861 listener.onPackagesSuspended(user, packages, launcherExtras);
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700862 } catch (RemoteException re) {
863 Slog.d(TAG, "Callback failed ", re);
864 }
Kenny Guy77242752016-01-15 13:29:06 +0000865 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700866 } finally {
867 mListeners.finishBroadcast();
Kenny Guy77242752016-01-15 13:29:06 +0000868 }
Kenny Guy77242752016-01-15 13:29:06 +0000869
Suprabh Shukla19b41f32018-03-26 22:35:13 -0700870 super.onPackagesSuspended(packages, launcherExtras);
Kenny Guy77242752016-01-15 13:29:06 +0000871 }
872
873 @Override
874 public void onPackagesUnsuspended(String[] packages) {
875 UserHandle user = new UserHandle(getChangingUserId());
876 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700877 try {
878 for (int i = 0; i < n; i++) {
879 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
880 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800881 if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnsuspended")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700882 try {
883 listener.onPackagesUnsuspended(user, packages);
884 } catch (RemoteException re) {
885 Slog.d(TAG, "Callback failed ", re);
886 }
Kenny Guy77242752016-01-15 13:29:06 +0000887 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700888 } finally {
889 mListeners.finishBroadcast();
Kenny Guy77242752016-01-15 13:29:06 +0000890 }
Kenny Guy77242752016-01-15 13:29:06 +0000891
892 super.onPackagesUnsuspended(packages);
893 }
894
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800895 @Override
896 public void onShortcutChanged(@NonNull String packageName,
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700897 @UserIdInt int userId) {
Makoto Onukiaa8b94a2016-03-17 13:14:05 -0700898 postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId));
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700899 }
900
901 private void onShortcutChangedInner(@NonNull String packageName,
902 @UserIdInt int userId) {
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700903 final int n = mListeners.beginBroadcast();
Makoto Onuki02f338e2016-07-29 09:40:40 -0700904 try {
905 final UserHandle user = UserHandle.of(userId);
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800906
Makoto Onuki02f338e2016-07-29 09:40:40 -0700907 for (int i = 0; i < n; i++) {
908 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
909 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800910 if (!isEnabledProfileOf(cookie.user, user, "onShortcutChanged")) continue;
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800911
Makoto Onuki02f338e2016-07-29 09:40:40 -0700912 final int launcherUserId = cookie.user.getIdentifier();
Makoto Onukid99c6f02016-03-28 11:02:54 -0700913
Makoto Onuki02f338e2016-07-29 09:40:40 -0700914 // Make sure the caller has the permission.
915 if (!mShortcutServiceInternal.hasShortcutHostPermission(
Makoto Onuki634cecb2017-10-13 17:10:48 -0700916 launcherUserId, cookie.packageName,
917 cookie.callingPid, cookie.callingUid)) {
Makoto Onuki02f338e2016-07-29 09:40:40 -0700918 continue;
919 }
920 // Each launcher has a different set of pinned shortcuts, so we need to do a
921 // query in here.
922 // (As of now, only one launcher has the permission at a time, so it's bit
923 // moot, but we may change the permission model eventually.)
924 final List<ShortcutInfo> list =
925 mShortcutServiceInternal.getShortcuts(launcherUserId,
926 cookie.packageName,
927 /* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
928 /* component= */ null,
929 ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
Makoto Onuki634cecb2017-10-13 17:10:48 -0700930 | ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED
931 , userId, cookie.callingPid, cookie.callingUid);
Makoto Onuki02f338e2016-07-29 09:40:40 -0700932 try {
933 listener.onShortcutChanged(user, packageName,
934 new ParceledListSlice<>(list));
935 } catch (RemoteException re) {
936 Slog.d(TAG, "Callback failed ", re);
937 }
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700938 }
Makoto Onuki02f338e2016-07-29 09:40:40 -0700939 } catch (RuntimeException e) {
940 // When the user is locked we get IllegalState, so just catch all.
941 Log.w(TAG, e.getMessage(), e);
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700942 } finally {
943 mListeners.finishBroadcast();
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800944 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800945 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700946 }
947
948 class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> {
949 @Override
950 public void onCallbackDied(T callback, Object cookie) {
951 checkCallbackCount();
952 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800953 }
954 }
Nicolas Prevotb6830192015-06-26 13:45:12 -0700955}