blob: 7bb782b9fadcc32163955f4fc6c91f6ce11c2903 [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;
Kenny Guy53fa4ec2014-04-29 14:24:18 +010023import android.app.AppGlobals;
Makoto Onuki1a342742018-04-26 14:56:59 -070024import android.app.IApplicationThread;
Sunny Goyala6be88a2017-01-12 16:27:58 -080025import android.app.PendingIntent;
Ricky Waie6a90382019-01-14 11:34:10 +000026import android.app.admin.DevicePolicyManager;
Varun Shah2546cef2019-01-11 15:50:54 -080027import android.app.usage.UsageStatsManagerInternal;
Amith Yamasani4f582632014-02-19 14:31:52 -080028import android.content.ComponentName;
29import android.content.Context;
30import android.content.Intent;
Sunny Goyala6be88a2017-01-12 16:27:58 -080031import android.content.IntentSender;
Kenny Guy53fa4ec2014-04-29 14:24:18 +010032import android.content.pm.ActivityInfo;
Kenny Guy77242752016-01-15 13:29:06 +000033import android.content.pm.ApplicationInfo;
Amith Yamasani4f582632014-02-19 14:31:52 -080034import android.content.pm.ILauncherApps;
35import android.content.pm.IOnAppsChangedListener;
Jon Miranda2b340a22019-01-25 14:03:49 -080036import android.content.pm.IPackageInstallerCallback;
Makoto Onuki1b296162020-01-28 15:56:49 -080037import android.content.pm.IPackageManager;
Ricky Waie346a492019-01-21 14:54:32 +000038import android.content.pm.LauncherApps;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -070039import android.content.pm.LauncherApps.ShortcutQuery;
Kenny Guy53fa4ec2014-04-29 14:24:18 +010040import android.content.pm.PackageInfo;
Jon Miranda2b340a22019-01-25 14:03:49 -080041import android.content.pm.PackageInstaller.SessionInfo;
Jeff Sharkeycd654482016-01-08 17:42:11 -070042import android.content.pm.PackageManager;
Todd Kennedy18211fd2017-06-06 09:15:46 -070043import android.content.pm.PackageManagerInternal;
Sunny Goyal6cbc2fe2015-11-24 09:34:20 -080044import android.content.pm.ParceledListSlice;
Amith Yamasani4f582632014-02-19 14:31:52 -080045import android.content.pm.ResolveInfo;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080046import android.content.pm.ShortcutInfo;
47import android.content.pm.ShortcutServiceInternal;
48import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
Makoto Onukie70b29e2018-04-03 16:44:39 -070049import android.content.pm.UserInfo;
Winson14ff7172019-10-23 10:42:27 -070050import android.content.pm.parsing.AndroidPackage;
Amith Yamasani4f582632014-02-19 14:31:52 -080051import android.graphics.Rect;
Kenny Guy466d2032014-07-23 12:23:35 +010052import android.net.Uri;
Amith Yamasani4f582632014-02-19 14:31:52 -080053import android.os.Binder;
54import android.os.Bundle;
Makoto Onukic5475d42016-03-25 10:54:07 -070055import android.os.Handler;
Amith Yamasani4f582632014-02-19 14:31:52 -080056import android.os.IInterface;
Makoto Onuki55046222016-03-08 10:49:47 -080057import android.os.ParcelFileDescriptor;
Amith Yamasani4f582632014-02-19 14:31:52 -080058import android.os.RemoteCallbackList;
59import android.os.RemoteException;
Jon Miranda2b340a22019-01-25 14:03:49 -080060import android.os.ServiceManager;
Amith Yamasani4f582632014-02-19 14:31:52 -080061import android.os.UserHandle;
Makoto Onukie70b29e2018-04-03 16:44:39 -070062import android.os.UserManager;
Sunny Goyal145c8f82018-02-15 14:27:09 -080063import android.os.UserManagerInternal;
Kenny Guy466d2032014-07-23 12:23:35 +010064import android.provider.Settings;
Amith Yamasani932249d2014-05-01 14:39:35 -070065import android.util.Log;
Suprabh Shuklad3278442019-08-27 15:58:03 -070066import android.util.Pair;
Amith Yamasani4f582632014-02-19 14:31:52 -080067import android.util.Slog;
68
Makoto Onuki7a6a05f2016-03-10 17:01:08 -080069import com.android.internal.annotations.VisibleForTesting;
Amith Yamasani4f582632014-02-19 14:31:52 -080070import com.android.internal.content.PackageMonitor;
Makoto Onukic5475d42016-03-25 10:54:07 -070071import com.android.internal.os.BackgroundThread;
Ricky Wai68e07222019-03-21 18:07:12 +000072import com.android.internal.util.ArrayUtils;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080073import com.android.server.LocalServices;
Amith Yamasanidf7db072014-06-01 10:41:13 -070074import com.android.server.SystemService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070075import com.android.server.wm.ActivityTaskManagerInternal;
Amith Yamasani4f582632014-02-19 14:31:52 -080076
Ricky Waicf134eb2018-10-10 09:26:32 +010077import java.util.ArrayList;
Makoto Onukide3c16c2017-01-26 11:39:31 -080078import java.util.Collections;
Ricky Waicf134eb2018-10-10 09:26:32 +010079import java.util.HashSet;
Amith Yamasani4f582632014-02-19 14:31:52 -080080import java.util.List;
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +000081import java.util.Objects;
Amith Yamasani4f582632014-02-19 14:31:52 -080082
83/**
84 * Service that manages requests and callbacks for launchers that support
Makoto Onuki6f7362d92016-03-04 13:39:41 -080085 * managed profiles.
Amith Yamasani4f582632014-02-19 14:31:52 -080086 */
Amith Yamasanidf7db072014-06-01 10:41:13 -070087public class LauncherAppsService extends SystemService {
88
89 private final LauncherAppsImpl mLauncherAppsImpl;
Amith Yamasani4f582632014-02-19 14:31:52 -080090
91 public LauncherAppsService(Context context) {
Amith Yamasanidf7db072014-06-01 10:41:13 -070092 super(context);
93 mLauncherAppsImpl = new LauncherAppsImpl(context);
Amith Yamasani4f582632014-02-19 14:31:52 -080094 }
95
Amith Yamasani4f582632014-02-19 14:31:52 -080096 @Override
Amith Yamasanidf7db072014-06-01 10:41:13 -070097 public void onStart() {
98 publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl);
99 }
100
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700101 static class BroadcastCookie {
102 public final UserHandle user;
103 public final String packageName;
Makoto Onuki634cecb2017-10-13 17:10:48 -0700104 public final int callingUid;
105 public final int callingPid;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700106
Makoto Onuki634cecb2017-10-13 17:10:48 -0700107 BroadcastCookie(UserHandle userHandle, String packageName, int callingPid, int callingUid) {
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700108 this.user = userHandle;
109 this.packageName = packageName;
Makoto Onuki634cecb2017-10-13 17:10:48 -0700110 this.callingUid = callingUid;
111 this.callingPid = callingPid;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700112 }
113 }
114
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800115 @VisibleForTesting
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800116 static class LauncherAppsImpl extends ILauncherApps.Stub {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700117 private static final boolean DEBUG = false;
118 private static final String TAG = "LauncherAppsService";
Ricky Waie346a492019-01-21 14:54:32 +0000119
Amith Yamasanidf7db072014-06-01 10:41:13 -0700120 private final Context mContext;
Makoto Onukie70b29e2018-04-03 16:44:39 -0700121 private final UserManager mUm;
Makoto Onuki1b296162020-01-28 15:56:49 -0800122 private final IPackageManager mIPM;
Sunny Goyal145c8f82018-02-15 14:27:09 -0800123 private final UserManagerInternal mUserManagerInternal;
Varun Shah2546cef2019-01-11 15:50:54 -0800124 private final UsageStatsManagerInternal mUsageStatsManagerInternal;
Makoto Onukiea11db12016-06-24 15:17:44 -0700125 private final ActivityManagerInternal mActivityManagerInternal;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700126 private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800127 private final ShortcutServiceInternal mShortcutServiceInternal;
Amith Yamasanidf7db072014-06-01 10:41:13 -0700128 private final PackageCallbackList<IOnAppsChangedListener> mListeners
129 = new PackageCallbackList<IOnAppsChangedListener>();
Ricky Waie6a90382019-01-14 11:34:10 +0000130 private final DevicePolicyManager mDpm;
Amith Yamasanidf7db072014-06-01 10:41:13 -0700131
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800132 private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700133
Makoto Onukic5475d42016-03-25 10:54:07 -0700134 private final Handler mCallbackHandler;
135
Jon Miranda2b340a22019-01-25 14:03:49 -0800136 private PackageInstallerService mPackageInstallerService;
137
Amith Yamasanidf7db072014-06-01 10:41:13 -0700138 public LauncherAppsImpl(Context context) {
139 mContext = context;
Makoto Onuki1b296162020-01-28 15:56:49 -0800140 mIPM = AppGlobals.getPackageManager();
Makoto Onukie70b29e2018-04-03 16:44:39 -0700141 mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000142 mUserManagerInternal = Objects.requireNonNull(
Sunny Goyal145c8f82018-02-15 14:27:09 -0800143 LocalServices.getService(UserManagerInternal.class));
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000144 mUsageStatsManagerInternal = Objects.requireNonNull(
Varun Shah2546cef2019-01-11 15:50:54 -0800145 LocalServices.getService(UsageStatsManagerInternal.class));
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000146 mActivityManagerInternal = Objects.requireNonNull(
Makoto Onukiea11db12016-06-24 15:17:44 -0700147 LocalServices.getService(ActivityManagerInternal.class));
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000148 mActivityTaskManagerInternal = Objects.requireNonNull(
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700149 LocalServices.getService(ActivityTaskManagerInternal.class));
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000150 mShortcutServiceInternal = Objects.requireNonNull(
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800151 LocalServices.getService(ShortcutServiceInternal.class));
152 mShortcutServiceInternal.addListener(mPackageMonitor);
Makoto Onukic5475d42016-03-25 10:54:07 -0700153 mCallbackHandler = BackgroundThread.getHandler();
Ricky Waie6a90382019-01-14 11:34:10 +0000154 mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
Amith Yamasanidf7db072014-06-01 10:41:13 -0700155 }
156
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800157 @VisibleForTesting
158 int injectBinderCallingUid() {
159 return getCallingUid();
160 }
161
Makoto Onuki634cecb2017-10-13 17:10:48 -0700162 @VisibleForTesting
163 int injectBinderCallingPid() {
164 return getCallingPid();
165 }
166
Makoto Onukiac214972016-04-04 10:19:45 -0700167 final int injectCallingUserId() {
168 return UserHandle.getUserId(injectBinderCallingUid());
169 }
170
171 @VisibleForTesting
172 long injectClearCallingIdentity() {
173 return Binder.clearCallingIdentity();
174 }
175
176 // Injection point.
177 @VisibleForTesting
178 void injectRestoreCallingIdentity(long token) {
179 Binder.restoreCallingIdentity(token);
180 }
181
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800182 private int getCallingUserId() {
183 return UserHandle.getUserId(injectBinderCallingUid());
184 }
185
Amith Yamasanidf7db072014-06-01 10:41:13 -0700186 /*
Jon Miranda2b340a22019-01-25 14:03:49 -0800187 * @see android.content.pm.ILauncherApps#addOnAppsChangedListener
Amith Yamasanidf7db072014-06-01 10:41:13 -0700188 */
189 @Override
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700190 public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener)
191 throws RemoteException {
Makoto Onuki5ba0d3e2016-04-11 14:03:46 -0700192 verifyCallingPackage(callingPackage);
Amith Yamasanidf7db072014-06-01 10:41:13 -0700193 synchronized (mListeners) {
Amith Yamasani932249d2014-05-01 14:39:35 -0700194 if (DEBUG) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700195 Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle());
Amith Yamasani932249d2014-05-01 14:39:35 -0700196 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700197 if (mListeners.getRegisteredCallbackCount() == 0) {
198 if (DEBUG) {
199 Log.d(TAG, "Starting package monitoring");
200 }
201 startWatchingPackageBroadcasts();
202 }
203 mListeners.unregister(listener);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700204 mListeners.register(listener, new BroadcastCookie(UserHandle.of(getCallingUserId()),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700205 callingPackage, injectBinderCallingPid(), injectBinderCallingUid()));
Amith Yamasani4f582632014-02-19 14:31:52 -0800206 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800207 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800208
Amith Yamasanidf7db072014-06-01 10:41:13 -0700209 /*
Jon Miranda2b340a22019-01-25 14:03:49 -0800210 * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener
Amith Yamasanidf7db072014-06-01 10:41:13 -0700211 */
212 @Override
213 public void removeOnAppsChangedListener(IOnAppsChangedListener listener)
214 throws RemoteException {
215 synchronized (mListeners) {
216 if (DEBUG) {
217 Log.d(TAG, "Removing listener from " + Binder.getCallingUserHandle());
218 }
219 mListeners.unregister(listener);
220 if (mListeners.getRegisteredCallbackCount() == 0) {
221 stopWatchingPackageBroadcasts();
222 }
223 }
224 }
225
226 /**
Jon Miranda2b340a22019-01-25 14:03:49 -0800227 * @see android.content.pm.ILauncherApps#registerPackageInstallerCallback
228 */
229 @Override
230 public void registerPackageInstallerCallback(String callingPackage,
231 IPackageInstallerCallback callback) {
232 verifyCallingPackage(callingPackage);
233 UserHandle callingIdUserHandle = new UserHandle(getCallingUserId());
234 getPackageInstallerService().registerCallback(callback, eventUserId ->
235 isEnabledProfileOf(callingIdUserHandle,
236 new UserHandle(eventUserId), "shouldReceiveEvent"));
237 }
238
239 @Override
240 public ParceledListSlice<SessionInfo> getAllSessions(String callingPackage) {
241 verifyCallingPackage(callingPackage);
242 List<SessionInfo> sessionInfos = new ArrayList<>();
243 int[] userIds = mUm.getEnabledProfileIds(getCallingUserId());
244 long token = Binder.clearCallingIdentity();
245 try {
246 for (int userId : userIds) {
247 sessionInfos.addAll(getPackageInstallerService().getAllSessions(userId)
248 .getList());
249 }
250 } finally {
251 Binder.restoreCallingIdentity(token);
252 }
253 return new ParceledListSlice<>(sessionInfos);
254 }
255
256 private PackageInstallerService getPackageInstallerService() {
257 if (mPackageInstallerService == null) {
258 mPackageInstallerService = ((PackageInstallerService) ((PackageManagerService)
259 ServiceManager.getService("package")).getPackageInstaller());
260 }
261 return mPackageInstallerService;
262 }
263
264 /**
Amith Yamasanidf7db072014-06-01 10:41:13 -0700265 * Register a receiver to watch for package broadcasts
266 */
267 private void startWatchingPackageBroadcasts() {
Makoto Onukic5475d42016-03-25 10:54:07 -0700268 mPackageMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler);
Amith Yamasanidf7db072014-06-01 10:41:13 -0700269 }
270
271 /**
272 * Unregister package broadcast receiver
273 */
274 private void stopWatchingPackageBroadcasts() {
Amith Yamasani932249d2014-05-01 14:39:35 -0700275 if (DEBUG) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700276 Log.d(TAG, "Stopped watching for packages");
Amith Yamasani932249d2014-05-01 14:39:35 -0700277 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700278 mPackageMonitor.unregister();
279 }
280
281 void checkCallbackCount() {
282 synchronized (mListeners) {
283 if (DEBUG) {
284 Log.d(TAG, "Callback count = " + mListeners.getRegisteredCallbackCount());
285 }
286 if (mListeners.getRegisteredCallbackCount() == 0) {
287 stopWatchingPackageBroadcasts();
288 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800289 }
290 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800291
Makoto Onukide3c16c2017-01-26 11:39:31 -0800292 /**
293 * Checks if the calling user is in the same group as {@code targetUser}, and allowed
294 * to access it.
295 *
296 * @return TRUE if the calling user can access {@code targetUserId}. FALSE if not *but
297 * they're still in the same profile group*.
298 *
299 * @throws SecurityException if the calling user and {@code targetUser} are not in the same
300 * group.
301 */
Sunny Goyal145c8f82018-02-15 14:27:09 -0800302 private boolean canAccessProfile(int targetUserId, String message) {
Makoto Onukie70b29e2018-04-03 16:44:39 -0700303 final int callingUserId = injectCallingUserId();
304
305 if (targetUserId == callingUserId) return true;
306
307 long ident = injectClearCallingIdentity();
308 try {
309 final UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
Bookatz029832a2019-10-04 16:50:22 -0700310 if (callingUserInfo != null && callingUserInfo.isProfile()) {
Makoto Onukie70b29e2018-04-03 16:44:39 -0700311 Slog.w(TAG, message + " for another profile "
312 + targetUserId + " from " + callingUserId + " not allowed");
313 return false;
314 }
315 } finally {
316 injectRestoreCallingIdentity(ident);
317 }
318
Sunny Goyal145c8f82018-02-15 14:27:09 -0800319 return mUserManagerInternal.isProfileAccessible(injectCallingUserId(), targetUserId,
320 message, true);
Amith Yamasani932249d2014-05-01 14:39:35 -0700321 }
322
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800323 @VisibleForTesting // We override it in unit tests
324 void verifyCallingPackage(String callingPackage) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800325 int packageUid = -1;
326 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700327 packageUid = AppGlobals.getPackageManager().getPackageUid(callingPackage,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600328 PackageManager.MATCH_DIRECT_BOOT_AWARE
329 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
Makoto Onuki3ee7f712016-03-10 17:28:55 -0800330 | PackageManager.MATCH_UNINSTALLED_PACKAGES,
331 UserHandle.getUserId(getCallingUid()));
Todd Kennedy18211fd2017-06-06 09:15:46 -0700332 } catch (RemoteException ignore) {
333 }
334 if (packageUid < 0) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800335 Log.e(TAG, "Package not found: " + callingPackage);
336 }
Todd Kennedy18211fd2017-06-06 09:15:46 -0700337 if (packageUid != injectBinderCallingUid()) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800338 throw new SecurityException("Calling package name mismatch");
339 }
340 }
341
Ricky Waicf134eb2018-10-10 09:26:32 +0100342 private ResolveInfo getHiddenAppActivityInfo(String packageName, int callingUid,
343 UserHandle user) {
344 Intent intent = new Intent();
Ricky Wai92cd0062019-02-14 20:23:22 +0000345 intent.setComponent(new ComponentName(packageName,
346 PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME));
Ricky Waicf134eb2018-10-10 09:26:32 +0100347 final PackageManagerInternal pmInt =
348 LocalServices.getService(PackageManagerInternal.class);
349 List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
Patrick Baumann182ea1c2019-11-18 13:43:11 -0800350 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Ricky Waicf134eb2018-10-10 09:26:32 +0100351 PackageManager.MATCH_DIRECT_BOOT_AWARE
352 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
353 callingUid, user.getIdentifier());
354 if (apps.size() > 0) {
355 return apps.get(0);
356 }
357 return null;
358 }
359
Amith Yamasani4f582632014-02-19 14:31:52 -0800360 @Override
Suprabh Shukla79000492018-12-24 17:03:02 -0800361 public boolean shouldHideFromSuggestions(String packageName, UserHandle user) {
362 if (!canAccessProfile(user.getIdentifier(), "cannot get shouldHideFromSuggestions")) {
363 return false;
364 }
365 final PackageManagerInternal pmi = LocalServices.getService(
366 PackageManagerInternal.class);
367 int flags = pmi.getDistractingPackageRestrictions(packageName, user.getIdentifier());
368 return (flags & PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS) != 0;
369 }
370
371 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800372 public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage,
Ricky Waicf134eb2018-10-10 09:26:32 +0100373 String packageName, UserHandle user) throws RemoteException {
374 ParceledListSlice<ResolveInfo> launcherActivities = queryActivitiesForUser(
375 callingPackage,
Sunny Goyala6be88a2017-01-12 16:27:58 -0800376 new Intent(Intent.ACTION_MAIN)
377 .addCategory(Intent.CATEGORY_LAUNCHER)
378 .setPackage(packageName),
379 user);
Ricky Wai13b0abe2018-10-23 11:03:02 +0100380 if (Settings.Global.getInt(mContext.getContentResolver(),
Michal Karpinski217d5972018-11-07 15:18:21 +0000381 Settings.Global.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED, 1) == 0) {
Ricky Waicf134eb2018-10-10 09:26:32 +0100382 return launcherActivities;
383 }
Ricky Wai10ceaf92019-01-14 10:39:40 +0000384 if (launcherActivities == null) {
385 // Cannot access profile, so we don't even return any hidden apps.
386 return null;
387 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100388
389 final int callingUid = injectBinderCallingUid();
Ricky Waie6a90382019-01-14 11:34:10 +0000390 final long ident = injectClearCallingIdentity();
391 try {
392 if (mUm.getUserInfo(user.getIdentifier()).isManagedProfile()) {
393 // Managed profile should not show hidden apps
Ricky Waicf134eb2018-10-10 09:26:32 +0100394 return launcherActivities;
395 }
Ricky Waie6a90382019-01-14 11:34:10 +0000396 if (mDpm.getDeviceOwnerComponentOnAnyUser() != null) {
397 // Device owner devices should not show hidden apps
398 return launcherActivities;
Ricky Waicf134eb2018-10-10 09:26:32 +0100399 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100400
Ricky Waie6a90382019-01-14 11:34:10 +0000401 final ArrayList<ResolveInfo> result = new ArrayList<>(launcherActivities.getList());
402 final PackageManagerInternal pmInt =
403 LocalServices.getService(PackageManagerInternal.class);
404 if (packageName != null) {
405 // If this hidden app should not be shown, return the original list.
406 // Otherwise, inject hidden activity that forwards user to app details page.
407 if (result.size() > 0) {
408 return launcherActivities;
409 }
410 ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName, /*flags*/ 0,
411 callingUid, user.getIdentifier());
Ricky Waia52e4262019-03-13 17:39:16 +0000412 if (shouldShowSyntheticActivity(user, appInfo)) {
Ricky Waie6a90382019-01-14 11:34:10 +0000413 ResolveInfo info = getHiddenAppActivityInfo(packageName, callingUid, user);
414 if (info != null) {
415 result.add(info);
416 }
417 }
418 return new ParceledListSlice<>(result);
419 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100420 final HashSet<String> visiblePackages = new HashSet<>();
421 for (ResolveInfo info : result) {
422 visiblePackages.add(info.activityInfo.packageName);
423 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100424 List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(0,
425 user.getIdentifier(), callingUid);
426 for (ApplicationInfo applicationInfo : installedPackages) {
427 if (!visiblePackages.contains(applicationInfo.packageName)) {
Ricky Waia52e4262019-03-13 17:39:16 +0000428 if (!shouldShowSyntheticActivity(user, applicationInfo)) {
Ricky Waicf134eb2018-10-10 09:26:32 +0100429 continue;
430 }
431 ResolveInfo info = getHiddenAppActivityInfo(applicationInfo.packageName,
432 callingUid, user);
433 if (info != null) {
434 result.add(info);
435 }
436 }
437 }
438 return new ParceledListSlice<>(result);
439 } finally {
440 injectRestoreCallingIdentity(ident);
441 }
442 }
443
Ricky Waia52e4262019-03-13 17:39:16 +0000444 private boolean shouldShowSyntheticActivity(UserHandle user, ApplicationInfo appInfo) {
Michal Karpinski08404a952018-11-15 17:46:00 +0000445 if (appInfo == null || appInfo.isSystemApp() || appInfo.isUpdatedSystemApp()) {
Ricky Waicf134eb2018-10-10 09:26:32 +0100446 return false;
447 }
Ricky Wai87577272019-01-24 19:18:25 +0000448 if (isManagedProfileAdmin(user, appInfo.packageName)) {
449 return false;
450 }
Ricky Wai68e07222019-03-21 18:07:12 +0000451 final PackageManagerInternal pmInt =
452 LocalServices.getService(PackageManagerInternal.class);
Winson14ff7172019-10-23 10:42:27 -0700453 final AndroidPackage pkg = pmInt.getPackage(appInfo.packageName);
Ricky Wai68e07222019-03-21 18:07:12 +0000454 if (pkg == null) {
455 // Should not happen, but we shouldn't be failing if it does
456 return false;
457 }
Ricky Wai3eb1cc62019-09-05 18:21:29 +0100458 // If app does not have any default enabled launcher activity or any permissions,
459 // the app can legitimately have no icon so we do not show the synthetic activity.
460 return requestsPermissions(pkg) && hasDefaultEnableLauncherActivity(
461 appInfo.packageName);
Ricky Wai68e07222019-03-21 18:07:12 +0000462 }
463
Winson14ff7172019-10-23 10:42:27 -0700464 private boolean requestsPermissions(@NonNull AndroidPackage pkg) {
465 return !ArrayUtils.isEmpty(pkg.getRequestedPermissions());
Ricky Wai3eb1cc62019-09-05 18:21:29 +0100466 }
467
468 private boolean hasDefaultEnableLauncherActivity(@NonNull String packageName) {
469 final PackageManagerInternal pmInt =
470 LocalServices.getService(PackageManagerInternal.class);
471 final Intent matchIntent = new Intent(Intent.ACTION_MAIN);
472 matchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
473 matchIntent.setPackage(packageName);
474 final List<ResolveInfo> infoList = pmInt.queryIntentActivities(matchIntent,
Patrick Baumann182ea1c2019-11-18 13:43:11 -0800475 matchIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
Ricky Wai3eb1cc62019-09-05 18:21:29 +0100476 PackageManager.MATCH_DISABLED_COMPONENTS, Binder.getCallingUid(),
477 getCallingUserId());
478 final int size = infoList.size();
479 for (int i = 0; i < size; i++) {
480 if (infoList.get(i).activityInfo.enabled) {
481 return true;
482 }
Ricky Wai68e07222019-03-21 18:07:12 +0000483 }
Ricky Wai3eb1cc62019-09-05 18:21:29 +0100484 return false;
Amith Yamasani4f582632014-02-19 14:31:52 -0800485 }
486
Ricky Wai87577272019-01-24 19:18:25 +0000487 private boolean isManagedProfileAdmin(UserHandle user, String packageName) {
488 final List<UserInfo> userInfoList = mUm.getProfiles(user.getIdentifier());
489 for (int i = 0; i < userInfoList.size(); i++) {
490 UserInfo userInfo = userInfoList.get(i);
491 if (!userInfo.isManagedProfile()) {
492 continue;
493 }
494 ComponentName componentName = mDpm.getProfileOwnerAsUser(userInfo.getUserHandle());
495 if (componentName == null) {
496 continue;
497 }
498 if (componentName.getPackageName().equals(packageName)) {
499 return true;
500 }
501 }
502 return false;
503 }
504
Amith Yamasani4f582632014-02-19 14:31:52 -0800505 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800506 public ActivityInfo resolveActivity(
507 String callingPackage, ComponentName component, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700508 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800509 if (!canAccessProfile(user.getIdentifier(), "Cannot resolve activity")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700510 return null;
Amith Yamasani4f582632014-02-19 14:31:52 -0800511 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800512
Todd Kennedy18211fd2017-06-06 09:15:46 -0700513 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700514 long ident = Binder.clearCallingIdentity();
515 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700516 final PackageManagerInternal pmInt =
517 LocalServices.getService(PackageManagerInternal.class);
518 return pmInt.getActivityInfo(component,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600519 PackageManager.MATCH_DIRECT_BOOT_AWARE
520 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700521 callingUid, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700522 } finally {
523 Binder.restoreCallingIdentity(ident);
524 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800525 }
526
527 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800528 public ParceledListSlice getShortcutConfigActivities(
529 String callingPackage, String packageName, UserHandle user)
Sunny Goyala6be88a2017-01-12 16:27:58 -0800530 throws RemoteException {
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800531 return queryActivitiesForUser(callingPackage,
Sunny Goyala6be88a2017-01-12 16:27:58 -0800532 new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName), user);
533 }
534
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800535 private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage,
536 Intent intent, UserHandle user) {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800537 if (!canAccessProfile(user.getIdentifier(), "Cannot retrieve activities")) {
Sunny Goyala6be88a2017-01-12 16:27:58 -0800538 return null;
539 }
540
Todd Kennedy18211fd2017-06-06 09:15:46 -0700541 final int callingUid = injectBinderCallingUid();
Sunny Goyala6be88a2017-01-12 16:27:58 -0800542 long ident = injectClearCallingIdentity();
543 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700544 final PackageManagerInternal pmInt =
545 LocalServices.getService(PackageManagerInternal.class);
546 List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
Patrick Baumann182ea1c2019-11-18 13:43:11 -0800547 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Sunny Goyala6be88a2017-01-12 16:27:58 -0800548 PackageManager.MATCH_DIRECT_BOOT_AWARE
549 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700550 callingUid, user.getIdentifier());
Sunny Goyala6be88a2017-01-12 16:27:58 -0800551 return new ParceledListSlice<>(apps);
552 } finally {
553 injectRestoreCallingIdentity(ident);
554 }
555 }
556
557 @Override
558 public IntentSender getShortcutConfigActivityIntent(String callingPackage,
559 ComponentName component, UserHandle user) throws RemoteException {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800560 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800561 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800562 return null;
563 }
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000564 Objects.requireNonNull(component);
Sunny Goyala6be88a2017-01-12 16:27:58 -0800565
566 // All right, create the sender.
567 Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component);
568 final long identity = Binder.clearCallingIdentity();
569 try {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800570 final PendingIntent pi = PendingIntent.getActivityAsUser(
Sunny Goyala6be88a2017-01-12 16:27:58 -0800571 mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
572 | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800573 null, user);
574 return pi == null ? null : pi.getIntentSender();
Sunny Goyala6be88a2017-01-12 16:27:58 -0800575 } finally {
576 Binder.restoreCallingIdentity(identity);
577 }
578 }
579
580 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800581 public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700582 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800583 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700584 return false;
Amith Yamasani4f582632014-02-19 14:31:52 -0800585 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800586
Todd Kennedy18211fd2017-06-06 09:15:46 -0700587 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700588 long ident = Binder.clearCallingIdentity();
589 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700590 final PackageManagerInternal pmInt =
591 LocalServices.getService(PackageManagerInternal.class);
592 PackageInfo info = pmInt.getPackageInfo(packageName,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600593 PackageManager.MATCH_DIRECT_BOOT_AWARE
594 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700595 callingUid, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700596 return info != null && info.applicationInfo.enabled;
597 } finally {
598 Binder.restoreCallingIdentity(ident);
599 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800600 }
601
602 @Override
Suprabh Shukla19b41f32018-03-26 22:35:13 -0700603 public Bundle getSuspendedPackageLauncherExtras(String packageName,
604 UserHandle user) {
605 if (!canAccessProfile(user.getIdentifier(), "Cannot get launcher extras")) {
606 return null;
607 }
608 final PackageManagerInternal pmi =
609 LocalServices.getService(PackageManagerInternal.class);
610 return pmi.getSuspendedPackageLauncherExtras(packageName, user.getIdentifier());
611 }
612
613 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800614 public ApplicationInfo getApplicationInfo(
615 String callingPackage, String packageName, int flags, UserHandle user)
Kenny Guy77242752016-01-15 13:29:06 +0000616 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800617 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Kenny Guy77242752016-01-15 13:29:06 +0000618 return null;
619 }
620
Todd Kennedy18211fd2017-06-06 09:15:46 -0700621 final int callingUid = injectBinderCallingUid();
Kenny Guy77242752016-01-15 13:29:06 +0000622 long ident = Binder.clearCallingIdentity();
623 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700624 final PackageManagerInternal pmInt =
625 LocalServices.getService(PackageManagerInternal.class);
626 ApplicationInfo info = pmInt.getApplicationInfo(packageName, flags,
627 callingUid, user.getIdentifier());
Kenny Guy77242752016-01-15 13:29:06 +0000628 return info;
629 } finally {
630 Binder.restoreCallingIdentity(ident);
631 }
632 }
633
Varun Shah2546cef2019-01-11 15:50:54 -0800634 @Override
635 public LauncherApps.AppUsageLimit getAppUsageLimit(String callingPackage,
636 String packageName, UserHandle user) {
637 verifyCallingPackage(callingPackage);
638 if (!canAccessProfile(user.getIdentifier(), "Cannot access usage limit")) {
639 return null;
640 }
Varun Shahe9abb752019-02-11 11:25:06 -0800641 if (!mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) {
642 throw new SecurityException("Caller is not the recents app");
Varun Shah2546cef2019-01-11 15:50:54 -0800643 }
644
645 final UsageStatsManagerInternal.AppUsageLimitData data =
646 mUsageStatsManagerInternal.getAppUsageLimit(packageName, user);
647 if (data == null) {
648 return null;
649 }
650 return new LauncherApps.AppUsageLimit(
Varun Shah9c6f72b2019-01-25 21:13:56 -0800651 data.getTotalUsageLimit(), data.getUsageRemaining());
Varun Shah2546cef2019-01-11 15:50:54 -0800652 }
653
Makoto Onukide3c16c2017-01-26 11:39:31 -0800654 private void ensureShortcutPermission(@NonNull String callingPackage) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800655 verifyCallingPackage(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700656 if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700657 callingPackage, injectBinderCallingPid(), injectBinderCallingUid())) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800658 throw new SecurityException("Caller can't access shortcut information");
659 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800660 }
661
662 @Override
663 public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
Makoto Onuki99302b52017-03-29 12:42:26 -0700664 String packageName, List shortcutIds, ComponentName componentName, int flags,
665 UserHandle targetUser) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800666 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800667 if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800668 return new ParceledListSlice<>(Collections.EMPTY_LIST);
Makoto Onukiac214972016-04-04 10:19:45 -0700669 }
Makoto Onukiabe84422016-04-07 09:41:19 -0700670 if (shortcutIds != null && packageName == null) {
671 throw new IllegalArgumentException(
672 "To query by shortcut ID, package name must also be set");
673 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800674
Felipe Lemef93ce172016-06-13 14:19:40 -0700675 // TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below.
676 return new ParceledListSlice<>((List<ShortcutInfo>)
Makoto Onukid99c6f02016-03-28 11:02:54 -0700677 mShortcutServiceInternal.getShortcuts(getCallingUserId(),
Makoto Onukiabe84422016-04-07 09:41:19 -0700678 callingPackage, changedSince, packageName, shortcutIds,
Makoto Onuki634cecb2017-10-13 17:10:48 -0700679 componentName, flags, targetUser.getIdentifier(),
680 injectBinderCallingPid(), injectBinderCallingUid()));
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800681 }
682
683 @Override
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800684 public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800685 UserHandle targetUser) {
686 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800687 if (!canAccessProfile(targetUser.getIdentifier(), "Cannot pin shortcuts")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800688 return;
689 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800690
Makoto Onukid99c6f02016-03-28 11:02:54 -0700691 mShortcutServiceInternal.pinShortcuts(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800692 callingPackage, packageName, ids, targetUser.getIdentifier());
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800693 }
694
695 @Override
Makoto Onukiabe84422016-04-07 09:41:19 -0700696 public int getShortcutIconResId(String callingPackage, String packageName, String id,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800697 int targetUserId) {
698 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800699 if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
Makoto Onukiac214972016-04-04 10:19:45 -0700700 return 0;
701 }
Makoto Onuki55046222016-03-08 10:49:47 -0800702
Makoto Onukid99c6f02016-03-28 11:02:54 -0700703 return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800704 callingPackage, packageName, id, targetUserId);
Makoto Onuki55046222016-03-08 10:49:47 -0800705 }
706
707 @Override
Makoto Onukiabe84422016-04-07 09:41:19 -0700708 public ParcelFileDescriptor getShortcutIconFd(String callingPackage,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800709 String packageName, String id, int targetUserId) {
710 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800711 if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
Makoto Onukiac214972016-04-04 10:19:45 -0700712 return null;
713 }
Makoto Onuki55046222016-03-08 10:49:47 -0800714
Makoto Onukid99c6f02016-03-28 11:02:54 -0700715 return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800716 callingPackage, packageName, id, targetUserId);
Makoto Onuki55046222016-03-08 10:49:47 -0800717 }
718
719 @Override
Makoto Onukid99c6f02016-03-28 11:02:54 -0700720 public boolean hasShortcutHostPermission(String callingPackage) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800721 verifyCallingPackage(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700722 return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700723 callingPackage, injectBinderCallingPid(), injectBinderCallingUid());
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800724 }
725
726 @Override
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700727 public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800728 Rect sourceBounds, Bundle startActivityOptions, int targetUserId) {
Makoto Onukid99c6f02016-03-28 11:02:54 -0700729 verifyCallingPackage(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800730 if (!canAccessProfile(targetUserId, "Cannot start activity")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800731 return false;
732 }
Makoto Onukiac214972016-04-04 10:19:45 -0700733
Makoto Onukid99c6f02016-03-28 11:02:54 -0700734 // Even without the permission, pinned shortcuts are always launchable.
735 if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800736 callingPackage, packageName, shortcutId, targetUserId)) {
737 ensureShortcutPermission(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700738 }
739
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700740 final Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
Makoto Onuki634cecb2017-10-13 17:10:48 -0700741 getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId,
742 injectBinderCallingPid(), injectBinderCallingUid());
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700743 if (intents == null || intents.length == 0) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700744 return false;
Makoto Onuki43204b82016-03-08 16:16:44 -0800745 }
746 // Note the target activity doesn't have to be exported.
747
Makoto Onuki7e5c3e82016-07-22 11:57:05 -0700748 intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Makoto Onuki0eed4412016-07-21 11:21:59 -0700749 intents[0].setSourceBounds(sourceBounds);
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700750
751 return startShortcutIntentsAsPublisher(
Makoto Onukide3c16c2017-01-26 11:39:31 -0800752 intents, packageName, startActivityOptions, targetUserId);
Makoto Onukiea11db12016-06-24 15:17:44 -0700753 }
754
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700755 private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents,
Makoto Onukiea11db12016-06-24 15:17:44 -0700756 @NonNull String publisherPackage, Bundle startActivityOptions, int userId) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700757 final int code;
Makoto Onuki43204b82016-03-08 16:16:44 -0800758 try {
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700759 code = mActivityTaskManagerInternal.startActivitiesAsPackage(publisherPackage,
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700760 userId, intents, startActivityOptions);
Bryce Lee7f936862017-05-09 15:33:18 -0700761 if (ActivityManager.isStartResultSuccessful(code)) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700762 return true; // Success
763 } else {
764 Log.e(TAG, "Couldn't start activity, code=" + code);
Makoto Onukiea11db12016-06-24 15:17:44 -0700765 }
Bryce Lee7f936862017-05-09 15:33:18 -0700766 return false;
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700767 } catch (SecurityException e) {
768 if (DEBUG) {
769 Slog.d(TAG, "SecurityException while launching intent", e);
770 }
771 return false;
Makoto Onuki43204b82016-03-08 16:16:44 -0800772 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800773 }
774
Kenny Guy77242752016-01-15 13:29:06 +0000775 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800776 public boolean isActivityEnabled(
777 String callingPackage, ComponentName component, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700778 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800779 if (!canAccessProfile(user.getIdentifier(), "Cannot check component")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700780 return false;
Amith Yamasani4f582632014-02-19 14:31:52 -0800781 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800782
Todd Kennedy18211fd2017-06-06 09:15:46 -0700783 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700784 long ident = Binder.clearCallingIdentity();
785 try {
Makoto Onuki1b296162020-01-28 15:56:49 -0800786 final int state = mIPM.getComponentEnabledSetting(component, user.getIdentifier());
787 switch (state) {
788 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
789 break; // Need to check the manifest's enabled state.
790 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
791 return true;
792 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
793 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
794 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
795 return false;
796 }
Todd Kennedy18211fd2017-06-06 09:15:46 -0700797 final PackageManagerInternal pmInt =
798 LocalServices.getService(PackageManagerInternal.class);
799 ActivityInfo info = pmInt.getActivityInfo(component,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600800 PackageManager.MATCH_DIRECT_BOOT_AWARE
801 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700802 callingUid, user.getIdentifier());
Makoto Onuki516020a2019-01-28 14:16:42 -0800803 // Note we don't check "exported" because if the caller has the same UID as the
804 // callee's UID, it can still be launched.
805 // (If an app doesn't export a front door activity and causes issues with the
806 // launcher, that's just the app's bug.)
807 return info != null && info.isEnabled();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700808 } finally {
809 Binder.restoreCallingIdentity(ident);
810 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800811 }
812
Amith Yamasani4f582632014-02-19 14:31:52 -0800813 @Override
Jon Miranda2b340a22019-01-25 14:03:49 -0800814 public void startSessionDetailsActivityAsUser(IApplicationThread caller,
815 String callingPackage, SessionInfo sessionInfo, Rect sourceBounds,
816 Bundle opts, UserHandle userHandle) throws RemoteException {
817 int userId = userHandle.getIdentifier();
818 if (!canAccessProfile(userId, "Cannot start details activity")) {
819 return;
820 }
821
822 Intent i = new Intent(Intent.ACTION_VIEW)
823 .setData(new Uri.Builder()
824 .scheme("market")
825 .authority("details")
826 .appendQueryParameter("id", sessionInfo.appPackageName)
827 .build())
828 .putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
829 .authority(callingPackage).build());
830 i.setSourceBounds(sourceBounds);
831
832 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage, i, opts,
833 userId);
834 }
835
836 @Override
Makoto Onuki1a342742018-04-26 14:56:59 -0700837 public void startActivityAsUser(IApplicationThread caller, String callingPackage,
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800838 ComponentName component, Rect sourceBounds,
Amith Yamasanidf7db072014-06-01 10:41:13 -0700839 Bundle opts, UserHandle user) throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800840 if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800841 return;
842 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700843
844 Intent launchIntent = new Intent(Intent.ACTION_MAIN);
845 launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Makoto Onuki347a6bd2016-07-19 11:13:08 -0700846 launchIntent.setSourceBounds(sourceBounds);
847 launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
848 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Kenny Guy2df18922014-07-17 13:01:25 +0100849 launchIntent.setPackage(component.getPackageName());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700850
Makoto Onuki1a342742018-04-26 14:56:59 -0700851 boolean canLaunch = false;
852
Todd Kennedy18211fd2017-06-06 09:15:46 -0700853 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700854 long ident = Binder.clearCallingIdentity();
855 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700856 final PackageManagerInternal pmInt =
857 LocalServices.getService(PackageManagerInternal.class);
Kenny Guy2df18922014-07-17 13:01:25 +0100858 // Check that the component actually has Intent.CATEGORY_LAUCNCHER
859 // as calling startActivityAsUser ignores the category and just
860 // resolves based on the component if present.
Todd Kennedy18211fd2017-06-06 09:15:46 -0700861 List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent,
Patrick Baumann182ea1c2019-11-18 13:43:11 -0800862 launchIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600863 PackageManager.MATCH_DIRECT_BOOT_AWARE
864 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700865 callingUid, user.getIdentifier());
Kenny Guy2df18922014-07-17 13:01:25 +0100866 final int size = apps.size();
867 for (int i = 0; i < size; ++i) {
868 ActivityInfo activityInfo = apps.get(i).activityInfo;
869 if (activityInfo.packageName.equals(component.getPackageName()) &&
870 activityInfo.name.equals(component.getClassName())) {
Sunny Goyal06ef5af2018-10-16 15:32:41 -0700871 if (!activityInfo.exported) {
872 throw new SecurityException("Cannot launch non-exported components "
873 + component);
874 }
875
Kenny Guy2df18922014-07-17 13:01:25 +0100876 // Found an activity with category launcher that matches
877 // this component so ok to launch.
Tony Mak12917c62018-01-15 15:17:13 +0000878 launchIntent.setPackage(null);
Kenny Guy2df18922014-07-17 13:01:25 +0100879 launchIntent.setComponent(component);
Makoto Onuki1a342742018-04-26 14:56:59 -0700880 canLaunch = true;
881 break;
Kenny Guy2df18922014-07-17 13:01:25 +0100882 }
883 }
Makoto Onuki1a342742018-04-26 14:56:59 -0700884 if (!canLaunch) {
885 throw new SecurityException("Attempt to launch activity without "
886 + " category Intent.CATEGORY_LAUNCHER " + component);
887 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700888 } finally {
889 Binder.restoreCallingIdentity(ident);
890 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700891 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,
Makoto Onuki1a342742018-04-26 14:56:59 -0700892 launchIntent, opts, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700893 }
894
Kenny Guy466d2032014-07-23 12:23:35 +0100895 @Override
Makoto Onuki1a342742018-04-26 14:56:59 -0700896 public void showAppDetailsAsUser(IApplicationThread caller,
897 String callingPackage, ComponentName component,
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800898 Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800899 if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800900 return;
901 }
Kenny Guy466d2032014-07-23 12:23:35 +0100902
Makoto Onuki1a342742018-04-26 14:56:59 -0700903 final Intent intent;
Kenny Guy466d2032014-07-23 12:23:35 +0100904 long ident = Binder.clearCallingIdentity();
905 try {
906 String packageName = component.getPackageName();
Makoto Onuki1a342742018-04-26 14:56:59 -0700907 intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Kenny Guy466d2032014-07-23 12:23:35 +0100908 Uri.fromParts("package", packageName, null));
Winson369aad02016-02-17 10:35:47 -0800909 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Kenny Guy466d2032014-07-23 12:23:35 +0100910 intent.setSourceBounds(sourceBounds);
Kenny Guy466d2032014-07-23 12:23:35 +0100911 } finally {
912 Binder.restoreCallingIdentity(ident);
913 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700914 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,
Makoto Onuki1a342742018-04-26 14:56:59 -0700915 intent, opts, user.getIdentifier());
Kenny Guy466d2032014-07-23 12:23:35 +0100916 }
917
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700918 /** Checks if user is a profile of or same as listeningUser.
919 * and the user is enabled. */
Sunny Goyal145c8f82018-02-15 14:27:09 -0800920 private boolean isEnabledProfileOf(UserHandle listeningUser, UserHandle user,
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700921 String debugMsg) {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800922 return mUserManagerInternal.isProfileAccessible(listeningUser.getIdentifier(),
923 user.getIdentifier(), debugMsg, false);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700924 }
925
Makoto Onukic5475d42016-03-25 10:54:07 -0700926 @VisibleForTesting
Makoto Onukiaa8b94a2016-03-17 13:14:05 -0700927 void postToPackageMonitorHandler(Runnable r) {
Makoto Onukic5475d42016-03-25 10:54:07 -0700928 mCallbackHandler.post(r);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700929 }
930
931 private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700932
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800933 // TODO Simplify with lambdas.
934
Amith Yamasanidf7db072014-06-01 10:41:13 -0700935 @Override
936 public void onPackageAdded(String packageName, int uid) {
937 UserHandle user = new UserHandle(getChangingUserId());
938 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700939 try {
940 for (int i = 0; i < n; i++) {
941 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
942 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800943 if (!isEnabledProfileOf(cookie.user, user, "onPackageAdded")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700944 try {
945 listener.onPackageAdded(user, packageName);
946 } catch (RemoteException re) {
947 Slog.d(TAG, "Callback failed ", re);
948 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700949 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700950 } finally {
951 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700952 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700953
954 super.onPackageAdded(packageName, uid);
955 }
956
957 @Override
958 public void onPackageRemoved(String packageName, int uid) {
959 UserHandle user = new UserHandle(getChangingUserId());
960 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700961 try {
962 for (int i = 0; i < n; i++) {
963 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
964 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800965 if (!isEnabledProfileOf(cookie.user, user, "onPackageRemoved")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700966 try {
967 listener.onPackageRemoved(user, packageName);
968 } catch (RemoteException re) {
969 Slog.d(TAG, "Callback failed ", re);
970 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700971 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700972 } finally {
973 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700974 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700975
976 super.onPackageRemoved(packageName, uid);
977 }
978
979 @Override
980 public void onPackageModified(String packageName) {
981 UserHandle user = new UserHandle(getChangingUserId());
982 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700983 try {
984 for (int i = 0; i < n; i++) {
985 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
986 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800987 if (!isEnabledProfileOf(cookie.user, user, "onPackageModified")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700988 try {
989 listener.onPackageChanged(user, packageName);
990 } catch (RemoteException re) {
991 Slog.d(TAG, "Callback failed ", re);
992 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700993 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -0700994 } finally {
995 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700996 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700997
998 super.onPackageModified(packageName);
999 }
1000
1001 @Override
1002 public void onPackagesAvailable(String[] packages) {
1003 UserHandle user = new UserHandle(getChangingUserId());
1004 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001005 try {
1006 for (int i = 0; i < n; i++) {
1007 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1008 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001009 if (!isEnabledProfileOf(cookie.user, user, "onPackagesAvailable")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001010 try {
1011 listener.onPackagesAvailable(user, packages, isReplacing());
1012 } catch (RemoteException re) {
1013 Slog.d(TAG, "Callback failed ", re);
1014 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001015 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001016 } finally {
1017 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001018 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001019
1020 super.onPackagesAvailable(packages);
1021 }
1022
1023 @Override
1024 public void onPackagesUnavailable(String[] packages) {
1025 UserHandle user = new UserHandle(getChangingUserId());
1026 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001027 try {
1028 for (int i = 0; i < n; i++) {
1029 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1030 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001031 if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnavailable")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001032 try {
1033 listener.onPackagesUnavailable(user, packages, isReplacing());
1034 } catch (RemoteException re) {
1035 Slog.d(TAG, "Callback failed ", re);
1036 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001037 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001038 } finally {
1039 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001040 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001041
1042 super.onPackagesUnavailable(packages);
1043 }
1044
Kenny Guy77242752016-01-15 13:29:06 +00001045 @Override
Suprabh Shuklad3278442019-08-27 15:58:03 -07001046 public void onPackagesSuspended(String[] packages) {
Kenny Guy77242752016-01-15 13:29:06 +00001047 UserHandle user = new UserHandle(getChangingUserId());
Suprabh Shuklad3278442019-08-27 15:58:03 -07001048 PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
1049 final ArrayList<Pair<String, Bundle>> packagesWithExtras = new ArrayList<>();
1050 final ArrayList<String> packagesWithoutExtras = new ArrayList<>();
1051 for (String pkg : packages) {
1052 final Bundle launcherExtras = pmi.getSuspendedPackageLauncherExtras(pkg,
1053 user.getIdentifier());
1054 if (launcherExtras != null) {
1055 packagesWithExtras.add(new Pair<>(pkg, launcherExtras));
1056 } else {
1057 packagesWithoutExtras.add(pkg);
1058 }
1059 }
1060 final String[] packagesNullExtras = packagesWithoutExtras.toArray(
1061 new String[packagesWithoutExtras.size()]);
Kenny Guy77242752016-01-15 13:29:06 +00001062 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001063 try {
1064 for (int i = 0; i < n; i++) {
1065 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1066 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001067 if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001068 try {
Suprabh Shuklad3278442019-08-27 15:58:03 -07001069 listener.onPackagesSuspended(user, packagesNullExtras, null);
1070 for (int idx = 0; idx < packagesWithExtras.size(); idx++) {
1071 Pair<String, Bundle> packageExtraPair = packagesWithExtras.get(idx);
1072 listener.onPackagesSuspended(user,
1073 new String[]{packageExtraPair.first},
1074 packageExtraPair.second);
1075 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001076 } catch (RemoteException re) {
1077 Slog.d(TAG, "Callback failed ", re);
1078 }
Kenny Guy77242752016-01-15 13:29:06 +00001079 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001080 } finally {
1081 mListeners.finishBroadcast();
Kenny Guy77242752016-01-15 13:29:06 +00001082 }
Kenny Guy77242752016-01-15 13:29:06 +00001083 }
1084
1085 @Override
1086 public void onPackagesUnsuspended(String[] packages) {
1087 UserHandle user = new UserHandle(getChangingUserId());
1088 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001089 try {
1090 for (int i = 0; i < n; i++) {
1091 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1092 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001093 if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnsuspended")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001094 try {
1095 listener.onPackagesUnsuspended(user, packages);
1096 } catch (RemoteException re) {
1097 Slog.d(TAG, "Callback failed ", re);
1098 }
Kenny Guy77242752016-01-15 13:29:06 +00001099 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001100 } finally {
1101 mListeners.finishBroadcast();
Kenny Guy77242752016-01-15 13:29:06 +00001102 }
Kenny Guy77242752016-01-15 13:29:06 +00001103
1104 super.onPackagesUnsuspended(packages);
1105 }
1106
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001107 @Override
1108 public void onShortcutChanged(@NonNull String packageName,
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001109 @UserIdInt int userId) {
Makoto Onukiaa8b94a2016-03-17 13:14:05 -07001110 postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId));
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001111 }
1112
1113 private void onShortcutChangedInner(@NonNull String packageName,
1114 @UserIdInt int userId) {
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001115 final int n = mListeners.beginBroadcast();
Makoto Onuki02f338e2016-07-29 09:40:40 -07001116 try {
1117 final UserHandle user = UserHandle.of(userId);
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001118
Makoto Onuki02f338e2016-07-29 09:40:40 -07001119 for (int i = 0; i < n; i++) {
1120 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1121 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001122 if (!isEnabledProfileOf(cookie.user, user, "onShortcutChanged")) continue;
Makoto Onuki2d5b4652016-03-11 16:09:54 -08001123
Makoto Onuki02f338e2016-07-29 09:40:40 -07001124 final int launcherUserId = cookie.user.getIdentifier();
Makoto Onukid99c6f02016-03-28 11:02:54 -07001125
Makoto Onuki02f338e2016-07-29 09:40:40 -07001126 // Make sure the caller has the permission.
1127 if (!mShortcutServiceInternal.hasShortcutHostPermission(
Makoto Onuki634cecb2017-10-13 17:10:48 -07001128 launcherUserId, cookie.packageName,
1129 cookie.callingPid, cookie.callingUid)) {
Makoto Onuki02f338e2016-07-29 09:40:40 -07001130 continue;
1131 }
1132 // Each launcher has a different set of pinned shortcuts, so we need to do a
1133 // query in here.
1134 // (As of now, only one launcher has the permission at a time, so it's bit
1135 // moot, but we may change the permission model eventually.)
1136 final List<ShortcutInfo> list =
1137 mShortcutServiceInternal.getShortcuts(launcherUserId,
1138 cookie.packageName,
1139 /* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
1140 /* component= */ null,
1141 ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
Makoto Onuki634cecb2017-10-13 17:10:48 -07001142 | ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED
1143 , userId, cookie.callingPid, cookie.callingUid);
Makoto Onuki02f338e2016-07-29 09:40:40 -07001144 try {
1145 listener.onShortcutChanged(user, packageName,
1146 new ParceledListSlice<>(list));
1147 } catch (RemoteException re) {
1148 Slog.d(TAG, "Callback failed ", re);
1149 }
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001150 }
Makoto Onuki02f338e2016-07-29 09:40:40 -07001151 } catch (RuntimeException e) {
1152 // When the user is locked we get IllegalState, so just catch all.
1153 Log.w(TAG, e.getMessage(), e);
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001154 } finally {
1155 mListeners.finishBroadcast();
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001156 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001157 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001158 }
1159
1160 class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> {
1161 @Override
1162 public void onCallbackDied(T callback, Object cookie) {
1163 checkCallbackCount();
1164 }
Amith Yamasani4f582632014-02-19 14:31:52 -08001165 }
1166 }
Nicolas Prevotb6830192015-06-26 13:45:12 -07001167}