blob: 9e9128430e014b1dc370d0093e6dd6622a9962f2 [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;
Ricky Waie346a492019-01-21 14:54:32 +000037import android.content.pm.LauncherApps;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -070038import android.content.pm.LauncherApps.ShortcutQuery;
Kenny Guy53fa4ec2014-04-29 14:24:18 +010039import android.content.pm.PackageInfo;
Jon Miranda2b340a22019-01-25 14:03:49 -080040import android.content.pm.PackageInstaller.SessionInfo;
Jeff Sharkeycd654482016-01-08 17:42:11 -070041import android.content.pm.PackageManager;
Todd Kennedy18211fd2017-06-06 09:15:46 -070042import android.content.pm.PackageManagerInternal;
Sunny Goyal6cbc2fe2015-11-24 09:34:20 -080043import android.content.pm.ParceledListSlice;
Amith Yamasani4f582632014-02-19 14:31:52 -080044import android.content.pm.ResolveInfo;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080045import android.content.pm.ShortcutInfo;
46import android.content.pm.ShortcutServiceInternal;
47import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
Ricky Waie346a492019-01-21 14:54:32 +000048import android.content.pm.Signature;
49import android.content.pm.SigningInfo;
Makoto Onukie70b29e2018-04-03 16:44:39 -070050import android.content.pm.UserInfo;
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;
Ricky Waie346a492019-01-21 14:54:32 +000065import android.util.ByteStringUtils;
Amith Yamasani932249d2014-05-01 14:39:35 -070066import android.util.Log;
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 Waie346a492019-01-21 14:54:32 +000072import com.android.internal.util.DumpUtils;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080073import com.android.internal.util.Preconditions;
Ricky Waie346a492019-01-21 14:54:32 +000074import com.android.internal.util.StatLogger;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080075import com.android.server.LocalServices;
Amith Yamasanidf7db072014-06-01 10:41:13 -070076import com.android.server.SystemService;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070077import com.android.server.wm.ActivityTaskManagerInternal;
Amith Yamasani4f582632014-02-19 14:31:52 -080078
Ricky Waie346a492019-01-21 14:54:32 +000079import java.io.FileDescriptor;
80import java.io.PrintWriter;
81import java.security.MessageDigest;
82import java.security.NoSuchAlgorithmException;
Ricky Waicf134eb2018-10-10 09:26:32 +010083import java.util.ArrayList;
Ricky Waie346a492019-01-21 14:54:32 +000084import java.util.Arrays;
Makoto Onukide3c16c2017-01-26 11:39:31 -080085import java.util.Collections;
Ricky Waicf134eb2018-10-10 09:26:32 +010086import java.util.HashSet;
Amith Yamasani4f582632014-02-19 14:31:52 -080087import java.util.List;
Ricky Waie346a492019-01-21 14:54:32 +000088import java.util.Set;
89import java.util.concurrent.ConcurrentHashMap;
Amith Yamasani4f582632014-02-19 14:31:52 -080090
91/**
92 * Service that manages requests and callbacks for launchers that support
Makoto Onuki6f7362d92016-03-04 13:39:41 -080093 * managed profiles.
Amith Yamasani4f582632014-02-19 14:31:52 -080094 */
Amith Yamasanidf7db072014-06-01 10:41:13 -070095public class LauncherAppsService extends SystemService {
96
97 private final LauncherAppsImpl mLauncherAppsImpl;
Amith Yamasani4f582632014-02-19 14:31:52 -080098
99 public LauncherAppsService(Context context) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700100 super(context);
101 mLauncherAppsImpl = new LauncherAppsImpl(context);
Amith Yamasani4f582632014-02-19 14:31:52 -0800102 }
103
Amith Yamasani4f582632014-02-19 14:31:52 -0800104 @Override
Amith Yamasanidf7db072014-06-01 10:41:13 -0700105 public void onStart() {
106 publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl);
107 }
108
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700109 static class BroadcastCookie {
110 public final UserHandle user;
111 public final String packageName;
Makoto Onuki634cecb2017-10-13 17:10:48 -0700112 public final int callingUid;
113 public final int callingPid;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700114
Makoto Onuki634cecb2017-10-13 17:10:48 -0700115 BroadcastCookie(UserHandle userHandle, String packageName, int callingPid, int callingUid) {
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700116 this.user = userHandle;
117 this.packageName = packageName;
Makoto Onuki634cecb2017-10-13 17:10:48 -0700118 this.callingUid = callingUid;
119 this.callingPid = callingPid;
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700120 }
121 }
122
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800123 @VisibleForTesting
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800124 static class LauncherAppsImpl extends ILauncherApps.Stub {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700125 private static final boolean DEBUG = false;
126 private static final String TAG = "LauncherAppsService";
Ricky Waie346a492019-01-21 14:54:32 +0000127
128 // Stats
129 @VisibleForTesting
130 interface Stats {
131 int INIT_VOUCHED_SIGNATURES = 0;
132 int COUNT = INIT_VOUCHED_SIGNATURES + 1;
133 }
134 private final StatLogger mStatLogger = new StatLogger(new String[] {
135 "initVouchedSignatures"
136 });
137
Amith Yamasanidf7db072014-06-01 10:41:13 -0700138 private final Context mContext;
Makoto Onukie70b29e2018-04-03 16:44:39 -0700139 private final UserManager mUm;
Sunny Goyal145c8f82018-02-15 14:27:09 -0800140 private final UserManagerInternal mUserManagerInternal;
Varun Shah2546cef2019-01-11 15:50:54 -0800141 private final UsageStatsManagerInternal mUsageStatsManagerInternal;
Makoto Onukiea11db12016-06-24 15:17:44 -0700142 private final ActivityManagerInternal mActivityManagerInternal;
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700143 private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800144 private final ShortcutServiceInternal mShortcutServiceInternal;
Amith Yamasanidf7db072014-06-01 10:41:13 -0700145 private final PackageCallbackList<IOnAppsChangedListener> mListeners
146 = new PackageCallbackList<IOnAppsChangedListener>();
Ricky Waie6a90382019-01-14 11:34:10 +0000147 private final DevicePolicyManager mDpm;
Ricky Waie346a492019-01-21 14:54:32 +0000148 private final ConcurrentHashMap<UserHandle, Set<String>> mVouchedSignaturesByUser;
149 private final Set<String> mVouchProviders;
Amith Yamasanidf7db072014-06-01 10:41:13 -0700150
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800151 private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
Ricky Waie346a492019-01-21 14:54:32 +0000152 private final VouchesChangedMonitor mVouchesChangedMonitor = new VouchesChangedMonitor();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700153
Makoto Onukic5475d42016-03-25 10:54:07 -0700154 private final Handler mCallbackHandler;
155
Ricky Waie346a492019-01-21 14:54:32 +0000156 private final Object mVouchedSignaturesLocked = new Object();
157
Jon Miranda2b340a22019-01-25 14:03:49 -0800158 private PackageInstallerService mPackageInstallerService;
159
Amith Yamasanidf7db072014-06-01 10:41:13 -0700160 public LauncherAppsImpl(Context context) {
161 mContext = context;
Makoto Onukie70b29e2018-04-03 16:44:39 -0700162 mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800163 mUserManagerInternal = Preconditions.checkNotNull(
164 LocalServices.getService(UserManagerInternal.class));
Varun Shah2546cef2019-01-11 15:50:54 -0800165 mUsageStatsManagerInternal = Preconditions.checkNotNull(
166 LocalServices.getService(UsageStatsManagerInternal.class));
Makoto Onukiea11db12016-06-24 15:17:44 -0700167 mActivityManagerInternal = Preconditions.checkNotNull(
168 LocalServices.getService(ActivityManagerInternal.class));
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700169 mActivityTaskManagerInternal = Preconditions.checkNotNull(
170 LocalServices.getService(ActivityTaskManagerInternal.class));
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800171 mShortcutServiceInternal = Preconditions.checkNotNull(
172 LocalServices.getService(ShortcutServiceInternal.class));
173 mShortcutServiceInternal.addListener(mPackageMonitor);
Makoto Onukic5475d42016-03-25 10:54:07 -0700174 mCallbackHandler = BackgroundThread.getHandler();
Ricky Waie6a90382019-01-14 11:34:10 +0000175 mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
Ricky Waie346a492019-01-21 14:54:32 +0000176 mVouchedSignaturesByUser = new ConcurrentHashMap<>();
177 mVouchProviders = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
178 mVouchesChangedMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler);
Amith Yamasanidf7db072014-06-01 10:41:13 -0700179 }
180
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800181 @VisibleForTesting
182 int injectBinderCallingUid() {
183 return getCallingUid();
184 }
185
Makoto Onuki634cecb2017-10-13 17:10:48 -0700186 @VisibleForTesting
187 int injectBinderCallingPid() {
188 return getCallingPid();
189 }
190
Makoto Onukiac214972016-04-04 10:19:45 -0700191 final int injectCallingUserId() {
192 return UserHandle.getUserId(injectBinderCallingUid());
193 }
194
195 @VisibleForTesting
196 long injectClearCallingIdentity() {
197 return Binder.clearCallingIdentity();
198 }
199
200 // Injection point.
201 @VisibleForTesting
202 void injectRestoreCallingIdentity(long token) {
203 Binder.restoreCallingIdentity(token);
204 }
205
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800206 private int getCallingUserId() {
207 return UserHandle.getUserId(injectBinderCallingUid());
208 }
209
Amith Yamasanidf7db072014-06-01 10:41:13 -0700210 /*
Jon Miranda2b340a22019-01-25 14:03:49 -0800211 * @see android.content.pm.ILauncherApps#addOnAppsChangedListener
Amith Yamasanidf7db072014-06-01 10:41:13 -0700212 */
213 @Override
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700214 public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener)
215 throws RemoteException {
Makoto Onuki5ba0d3e2016-04-11 14:03:46 -0700216 verifyCallingPackage(callingPackage);
Amith Yamasanidf7db072014-06-01 10:41:13 -0700217 synchronized (mListeners) {
Amith Yamasani932249d2014-05-01 14:39:35 -0700218 if (DEBUG) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700219 Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle());
Amith Yamasani932249d2014-05-01 14:39:35 -0700220 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700221 if (mListeners.getRegisteredCallbackCount() == 0) {
222 if (DEBUG) {
223 Log.d(TAG, "Starting package monitoring");
224 }
225 startWatchingPackageBroadcasts();
226 }
227 mListeners.unregister(listener);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -0700228 mListeners.register(listener, new BroadcastCookie(UserHandle.of(getCallingUserId()),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700229 callingPackage, injectBinderCallingPid(), injectBinderCallingUid()));
Amith Yamasani4f582632014-02-19 14:31:52 -0800230 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800231 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800232
Amith Yamasanidf7db072014-06-01 10:41:13 -0700233 /*
Jon Miranda2b340a22019-01-25 14:03:49 -0800234 * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener
Amith Yamasanidf7db072014-06-01 10:41:13 -0700235 */
236 @Override
237 public void removeOnAppsChangedListener(IOnAppsChangedListener listener)
238 throws RemoteException {
239 synchronized (mListeners) {
240 if (DEBUG) {
241 Log.d(TAG, "Removing listener from " + Binder.getCallingUserHandle());
242 }
243 mListeners.unregister(listener);
244 if (mListeners.getRegisteredCallbackCount() == 0) {
245 stopWatchingPackageBroadcasts();
246 }
247 }
248 }
249
250 /**
Jon Miranda2b340a22019-01-25 14:03:49 -0800251 * @see android.content.pm.ILauncherApps#registerPackageInstallerCallback
252 */
253 @Override
254 public void registerPackageInstallerCallback(String callingPackage,
255 IPackageInstallerCallback callback) {
256 verifyCallingPackage(callingPackage);
257 UserHandle callingIdUserHandle = new UserHandle(getCallingUserId());
258 getPackageInstallerService().registerCallback(callback, eventUserId ->
259 isEnabledProfileOf(callingIdUserHandle,
260 new UserHandle(eventUserId), "shouldReceiveEvent"));
261 }
262
263 @Override
264 public ParceledListSlice<SessionInfo> getAllSessions(String callingPackage) {
265 verifyCallingPackage(callingPackage);
266 List<SessionInfo> sessionInfos = new ArrayList<>();
267 int[] userIds = mUm.getEnabledProfileIds(getCallingUserId());
268 long token = Binder.clearCallingIdentity();
269 try {
270 for (int userId : userIds) {
271 sessionInfos.addAll(getPackageInstallerService().getAllSessions(userId)
272 .getList());
273 }
274 } finally {
275 Binder.restoreCallingIdentity(token);
276 }
277 return new ParceledListSlice<>(sessionInfos);
278 }
279
280 private PackageInstallerService getPackageInstallerService() {
281 if (mPackageInstallerService == null) {
282 mPackageInstallerService = ((PackageInstallerService) ((PackageManagerService)
283 ServiceManager.getService("package")).getPackageInstaller());
284 }
285 return mPackageInstallerService;
286 }
287
288 /**
Amith Yamasanidf7db072014-06-01 10:41:13 -0700289 * Register a receiver to watch for package broadcasts
290 */
291 private void startWatchingPackageBroadcasts() {
Makoto Onukic5475d42016-03-25 10:54:07 -0700292 mPackageMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler);
Amith Yamasanidf7db072014-06-01 10:41:13 -0700293 }
294
295 /**
296 * Unregister package broadcast receiver
297 */
298 private void stopWatchingPackageBroadcasts() {
Amith Yamasani932249d2014-05-01 14:39:35 -0700299 if (DEBUG) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700300 Log.d(TAG, "Stopped watching for packages");
Amith Yamasani932249d2014-05-01 14:39:35 -0700301 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700302 mPackageMonitor.unregister();
303 }
304
305 void checkCallbackCount() {
306 synchronized (mListeners) {
307 if (DEBUG) {
308 Log.d(TAG, "Callback count = " + mListeners.getRegisteredCallbackCount());
309 }
310 if (mListeners.getRegisteredCallbackCount() == 0) {
311 stopWatchingPackageBroadcasts();
312 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800313 }
314 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800315
Makoto Onukide3c16c2017-01-26 11:39:31 -0800316 /**
317 * Checks if the calling user is in the same group as {@code targetUser}, and allowed
318 * to access it.
319 *
320 * @return TRUE if the calling user can access {@code targetUserId}. FALSE if not *but
321 * they're still in the same profile group*.
322 *
323 * @throws SecurityException if the calling user and {@code targetUser} are not in the same
324 * group.
325 */
Sunny Goyal145c8f82018-02-15 14:27:09 -0800326 private boolean canAccessProfile(int targetUserId, String message) {
Makoto Onukie70b29e2018-04-03 16:44:39 -0700327 final int callingUserId = injectCallingUserId();
328
329 if (targetUserId == callingUserId) return true;
330
331 long ident = injectClearCallingIdentity();
332 try {
333 final UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
334 if (callingUserInfo != null && callingUserInfo.isManagedProfile()) {
335 Slog.w(TAG, message + " for another profile "
336 + targetUserId + " from " + callingUserId + " not allowed");
337 return false;
338 }
339 } finally {
340 injectRestoreCallingIdentity(ident);
341 }
342
Sunny Goyal145c8f82018-02-15 14:27:09 -0800343 return mUserManagerInternal.isProfileAccessible(injectCallingUserId(), targetUserId,
344 message, true);
Amith Yamasani932249d2014-05-01 14:39:35 -0700345 }
346
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800347 @VisibleForTesting // We override it in unit tests
348 void verifyCallingPackage(String callingPackage) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800349 int packageUid = -1;
350 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700351 packageUid = AppGlobals.getPackageManager().getPackageUid(callingPackage,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600352 PackageManager.MATCH_DIRECT_BOOT_AWARE
353 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
Makoto Onuki3ee7f712016-03-10 17:28:55 -0800354 | PackageManager.MATCH_UNINSTALLED_PACKAGES,
355 UserHandle.getUserId(getCallingUid()));
Todd Kennedy18211fd2017-06-06 09:15:46 -0700356 } catch (RemoteException ignore) {
357 }
358 if (packageUid < 0) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800359 Log.e(TAG, "Package not found: " + callingPackage);
360 }
Todd Kennedy18211fd2017-06-06 09:15:46 -0700361 if (packageUid != injectBinderCallingUid()) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800362 throw new SecurityException("Calling package name mismatch");
363 }
364 }
365
Ricky Waicf134eb2018-10-10 09:26:32 +0100366 private ResolveInfo getHiddenAppActivityInfo(String packageName, int callingUid,
367 UserHandle user) {
368 Intent intent = new Intent();
Ricky Wai92cd0062019-02-14 20:23:22 +0000369 intent.setComponent(new ComponentName(packageName,
370 PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME));
Ricky Waicf134eb2018-10-10 09:26:32 +0100371 final PackageManagerInternal pmInt =
372 LocalServices.getService(PackageManagerInternal.class);
373 List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
374 PackageManager.MATCH_DIRECT_BOOT_AWARE
375 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
376 callingUid, user.getIdentifier());
377 if (apps.size() > 0) {
378 return apps.get(0);
379 }
380 return null;
381 }
382
Amith Yamasani4f582632014-02-19 14:31:52 -0800383 @Override
Suprabh Shukla79000492018-12-24 17:03:02 -0800384 public boolean shouldHideFromSuggestions(String packageName, UserHandle user) {
385 if (!canAccessProfile(user.getIdentifier(), "cannot get shouldHideFromSuggestions")) {
386 return false;
387 }
388 final PackageManagerInternal pmi = LocalServices.getService(
389 PackageManagerInternal.class);
390 int flags = pmi.getDistractingPackageRestrictions(packageName, user.getIdentifier());
391 return (flags & PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS) != 0;
392 }
393
394 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800395 public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage,
Ricky Waicf134eb2018-10-10 09:26:32 +0100396 String packageName, UserHandle user) throws RemoteException {
397 ParceledListSlice<ResolveInfo> launcherActivities = queryActivitiesForUser(
398 callingPackage,
Sunny Goyala6be88a2017-01-12 16:27:58 -0800399 new Intent(Intent.ACTION_MAIN)
400 .addCategory(Intent.CATEGORY_LAUNCHER)
401 .setPackage(packageName),
402 user);
Ricky Wai13b0abe2018-10-23 11:03:02 +0100403 if (Settings.Global.getInt(mContext.getContentResolver(),
Michal Karpinski217d5972018-11-07 15:18:21 +0000404 Settings.Global.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED, 1) == 0) {
Ricky Waicf134eb2018-10-10 09:26:32 +0100405 return launcherActivities;
406 }
Ricky Wai10ceaf92019-01-14 10:39:40 +0000407 if (launcherActivities == null) {
408 // Cannot access profile, so we don't even return any hidden apps.
409 return null;
410 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100411
412 final int callingUid = injectBinderCallingUid();
Ricky Waie6a90382019-01-14 11:34:10 +0000413 final long ident = injectClearCallingIdentity();
414 try {
415 if (mUm.getUserInfo(user.getIdentifier()).isManagedProfile()) {
416 // Managed profile should not show hidden apps
Ricky Waicf134eb2018-10-10 09:26:32 +0100417 return launcherActivities;
418 }
Ricky Waie6a90382019-01-14 11:34:10 +0000419 if (mDpm.getDeviceOwnerComponentOnAnyUser() != null) {
420 // Device owner devices should not show hidden apps
421 return launcherActivities;
Ricky Waicf134eb2018-10-10 09:26:32 +0100422 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100423
Ricky Waie6a90382019-01-14 11:34:10 +0000424 final ArrayList<ResolveInfo> result = new ArrayList<>(launcherActivities.getList());
425 final PackageManagerInternal pmInt =
426 LocalServices.getService(PackageManagerInternal.class);
427 if (packageName != null) {
428 // If this hidden app should not be shown, return the original list.
429 // Otherwise, inject hidden activity that forwards user to app details page.
430 if (result.size() > 0) {
431 return launcherActivities;
432 }
433 ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName, /*flags*/ 0,
434 callingUid, user.getIdentifier());
Ricky Waie346a492019-01-21 14:54:32 +0000435 if (shouldShowHiddenApp(user, appInfo)) {
Ricky Waie6a90382019-01-14 11:34:10 +0000436 ResolveInfo info = getHiddenAppActivityInfo(packageName, callingUid, user);
437 if (info != null) {
438 result.add(info);
439 }
440 }
441 return new ParceledListSlice<>(result);
442 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100443 final HashSet<String> visiblePackages = new HashSet<>();
444 for (ResolveInfo info : result) {
445 visiblePackages.add(info.activityInfo.packageName);
446 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100447 List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(0,
448 user.getIdentifier(), callingUid);
449 for (ApplicationInfo applicationInfo : installedPackages) {
450 if (!visiblePackages.contains(applicationInfo.packageName)) {
Ricky Waie346a492019-01-21 14:54:32 +0000451 if (!shouldShowHiddenApp(user, applicationInfo)) {
Ricky Waicf134eb2018-10-10 09:26:32 +0100452 continue;
453 }
454 ResolveInfo info = getHiddenAppActivityInfo(applicationInfo.packageName,
455 callingUid, user);
456 if (info != null) {
457 result.add(info);
458 }
459 }
460 }
461 return new ParceledListSlice<>(result);
462 } finally {
463 injectRestoreCallingIdentity(ident);
464 }
465 }
466
Ricky Waie346a492019-01-21 14:54:32 +0000467 private boolean shouldShowHiddenApp(UserHandle user, ApplicationInfo appInfo) {
Michal Karpinski08404a952018-11-15 17:46:00 +0000468 if (appInfo == null || appInfo.isSystemApp() || appInfo.isUpdatedSystemApp()) {
Ricky Waicf134eb2018-10-10 09:26:32 +0100469 return false;
470 }
Ricky Waie346a492019-01-21 14:54:32 +0000471 if (!mVouchedSignaturesByUser.containsKey(user)) {
472 initVouchedSignatures(user);
473 }
Ricky Wai87577272019-01-24 19:18:25 +0000474 if (isManagedProfileAdmin(user, appInfo.packageName)) {
475 return false;
476 }
Ricky Waie346a492019-01-21 14:54:32 +0000477 if (mVouchProviders.contains(appInfo.packageName)) {
478 // If it's a vouching packages then we must show hidden app
479 return true;
480 }
481 // If app's signature is in vouch list, do not show hidden app
482 final Set<String> vouches = mVouchedSignaturesByUser.get(user);
483 try {
484 final PackageInfo pkgInfo = mContext.getPackageManager().getPackageInfo(
485 appInfo.packageName, PackageManager.GET_SIGNING_CERTIFICATES);
486 final Signature[] signatures = getLatestSignatures(pkgInfo.signingInfo);
487 // If any of the signatures appears in vouches, then we don't show hidden app
488 for (Signature signature : signatures) {
489 final String certDigest = computePackageCertDigest(signature);
490 if (vouches.contains(certDigest)) {
491 return false;
492 }
493 }
494 } catch (PackageManager.NameNotFoundException e) {
495 // Should not happen
496 }
Ricky Waicf134eb2018-10-10 09:26:32 +0100497 return true;
Amith Yamasani4f582632014-02-19 14:31:52 -0800498 }
499
Ricky Wai87577272019-01-24 19:18:25 +0000500 private boolean isManagedProfileAdmin(UserHandle user, String packageName) {
501 final List<UserInfo> userInfoList = mUm.getProfiles(user.getIdentifier());
502 for (int i = 0; i < userInfoList.size(); i++) {
503 UserInfo userInfo = userInfoList.get(i);
504 if (!userInfo.isManagedProfile()) {
505 continue;
506 }
507 ComponentName componentName = mDpm.getProfileOwnerAsUser(userInfo.getUserHandle());
508 if (componentName == null) {
509 continue;
510 }
511 if (componentName.getPackageName().equals(packageName)) {
512 return true;
513 }
514 }
515 return false;
516 }
517
Ricky Waie346a492019-01-21 14:54:32 +0000518 @VisibleForTesting
519 static String computePackageCertDigest(Signature signature) {
520 MessageDigest messageDigest;
521 try {
522 messageDigest = MessageDigest.getInstance("SHA1");
523 } catch (NoSuchAlgorithmException e) {
524 // Should not happen
525 return null;
526 }
527 messageDigest.update(signature.toByteArray());
528 final byte[] digest = messageDigest.digest();
529 return ByteStringUtils.toHexString(digest);
530 }
531
532 @VisibleForTesting
533 static Signature[] getLatestSignatures(SigningInfo signingInfo) {
534 if (signingInfo.hasMultipleSigners()) {
535 return signingInfo.getApkContentsSigners();
536 } else {
537 final Signature[] signatures = signingInfo.getSigningCertificateHistory();
538 return new Signature[]{signatures[0]};
539 }
540 }
541
542 private void updateVouches(String packageName, UserHandle user) {
543 final PackageManagerInternal pmInt =
544 LocalServices.getService(PackageManagerInternal.class);
545 ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName,
546 PackageManager.GET_META_DATA, Binder.getCallingUid(), user.getIdentifier());
547 if (appInfo == null) {
548 Log.w(TAG, "appInfo " + packageName + " is null");
549 return;
550 }
551 updateVouches(appInfo, user);
552 }
553
554 private void updateVouches(ApplicationInfo appInfo, UserHandle user) {
555 if (appInfo == null || appInfo.metaData == null) {
556 // No meta-data
557 return;
558 }
559 int tokenResourceId = appInfo.metaData.getInt(LauncherApps.VOUCHED_CERTS_KEY);
560 if (tokenResourceId == 0) {
561 // No xml file
562 return;
563 }
564 mVouchProviders.add(appInfo.packageName);
565 Set<String> vouches = mVouchedSignaturesByUser.get(user);
566 try {
567 List<String> signatures = Arrays.asList(
568 mContext.getPackageManager().getResourcesForApplication(
569 appInfo.packageName).getStringArray(tokenResourceId));
570 for (String signature : signatures) {
571 vouches.add(signature.toUpperCase());
572 }
573 } catch (PackageManager.NameNotFoundException e) {
574 // Should not happen
575 }
576 }
577
578 private void initVouchedSignatures(UserHandle user) {
579 synchronized (mVouchedSignaturesLocked) {
580 if (mVouchedSignaturesByUser.contains(user)) {
581 return;
582 }
583 final long startTime = mStatLogger.getTime();
584
585 Set<String> vouches = Collections.newSetFromMap(
586 new ConcurrentHashMap<String, Boolean>());
587
588 final int callingUid = injectBinderCallingUid();
589 long ident = Binder.clearCallingIdentity();
590 try {
591 final PackageManagerInternal pmInt =
592 LocalServices.getService(PackageManagerInternal.class);
593 List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(
594 PackageManager.GET_META_DATA, user.getIdentifier(), callingUid);
595 for (ApplicationInfo appInfo : installedPackages) {
596 updateVouches(appInfo, user);
597 }
598 } finally {
599 Binder.restoreCallingIdentity(ident);
600 }
601 mVouchedSignaturesByUser.putIfAbsent(user, vouches);
602 mStatLogger.logDurationStat(Stats.INIT_VOUCHED_SIGNATURES, startTime);
603 }
604 }
605
606 @Override
607 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
608 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
609 mStatLogger.dump(pw, " ");
610 }
611
Amith Yamasani4f582632014-02-19 14:31:52 -0800612 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800613 public ActivityInfo resolveActivity(
614 String callingPackage, ComponentName component, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700615 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800616 if (!canAccessProfile(user.getIdentifier(), "Cannot resolve activity")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700617 return null;
Amith Yamasani4f582632014-02-19 14:31:52 -0800618 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800619
Todd Kennedy18211fd2017-06-06 09:15:46 -0700620 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700621 long ident = Binder.clearCallingIdentity();
622 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700623 final PackageManagerInternal pmInt =
624 LocalServices.getService(PackageManagerInternal.class);
625 return pmInt.getActivityInfo(component,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600626 PackageManager.MATCH_DIRECT_BOOT_AWARE
627 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700628 callingUid, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700629 } finally {
630 Binder.restoreCallingIdentity(ident);
631 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800632 }
633
634 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800635 public ParceledListSlice getShortcutConfigActivities(
636 String callingPackage, String packageName, UserHandle user)
Sunny Goyala6be88a2017-01-12 16:27:58 -0800637 throws RemoteException {
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800638 return queryActivitiesForUser(callingPackage,
Sunny Goyala6be88a2017-01-12 16:27:58 -0800639 new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName), user);
640 }
641
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800642 private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage,
643 Intent intent, UserHandle user) {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800644 if (!canAccessProfile(user.getIdentifier(), "Cannot retrieve activities")) {
Sunny Goyala6be88a2017-01-12 16:27:58 -0800645 return null;
646 }
647
Todd Kennedy18211fd2017-06-06 09:15:46 -0700648 final int callingUid = injectBinderCallingUid();
Sunny Goyala6be88a2017-01-12 16:27:58 -0800649 long ident = injectClearCallingIdentity();
650 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700651 final PackageManagerInternal pmInt =
652 LocalServices.getService(PackageManagerInternal.class);
653 List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
Sunny Goyala6be88a2017-01-12 16:27:58 -0800654 PackageManager.MATCH_DIRECT_BOOT_AWARE
655 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700656 callingUid, user.getIdentifier());
Sunny Goyala6be88a2017-01-12 16:27:58 -0800657 return new ParceledListSlice<>(apps);
658 } finally {
659 injectRestoreCallingIdentity(ident);
660 }
661 }
662
663 @Override
664 public IntentSender getShortcutConfigActivityIntent(String callingPackage,
665 ComponentName component, UserHandle user) throws RemoteException {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800666 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800667 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800668 return null;
669 }
Sunny Goyala6be88a2017-01-12 16:27:58 -0800670 Preconditions.checkNotNull(component);
Sunny Goyala6be88a2017-01-12 16:27:58 -0800671
672 // All right, create the sender.
673 Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component);
674 final long identity = Binder.clearCallingIdentity();
675 try {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800676 final PendingIntent pi = PendingIntent.getActivityAsUser(
Sunny Goyala6be88a2017-01-12 16:27:58 -0800677 mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
678 | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800679 null, user);
680 return pi == null ? null : pi.getIntentSender();
Sunny Goyala6be88a2017-01-12 16:27:58 -0800681 } finally {
682 Binder.restoreCallingIdentity(identity);
683 }
684 }
685
686 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800687 public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700688 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800689 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700690 return false;
Amith Yamasani4f582632014-02-19 14:31:52 -0800691 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800692
Todd Kennedy18211fd2017-06-06 09:15:46 -0700693 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700694 long ident = Binder.clearCallingIdentity();
695 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700696 final PackageManagerInternal pmInt =
697 LocalServices.getService(PackageManagerInternal.class);
698 PackageInfo info = pmInt.getPackageInfo(packageName,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600699 PackageManager.MATCH_DIRECT_BOOT_AWARE
700 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700701 callingUid, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700702 return info != null && info.applicationInfo.enabled;
703 } finally {
704 Binder.restoreCallingIdentity(ident);
705 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800706 }
707
708 @Override
Suprabh Shukla19b41f32018-03-26 22:35:13 -0700709 public Bundle getSuspendedPackageLauncherExtras(String packageName,
710 UserHandle user) {
711 if (!canAccessProfile(user.getIdentifier(), "Cannot get launcher extras")) {
712 return null;
713 }
714 final PackageManagerInternal pmi =
715 LocalServices.getService(PackageManagerInternal.class);
716 return pmi.getSuspendedPackageLauncherExtras(packageName, user.getIdentifier());
717 }
718
719 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800720 public ApplicationInfo getApplicationInfo(
721 String callingPackage, String packageName, int flags, UserHandle user)
Kenny Guy77242752016-01-15 13:29:06 +0000722 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800723 if (!canAccessProfile(user.getIdentifier(), "Cannot check package")) {
Kenny Guy77242752016-01-15 13:29:06 +0000724 return null;
725 }
726
Todd Kennedy18211fd2017-06-06 09:15:46 -0700727 final int callingUid = injectBinderCallingUid();
Kenny Guy77242752016-01-15 13:29:06 +0000728 long ident = Binder.clearCallingIdentity();
729 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700730 final PackageManagerInternal pmInt =
731 LocalServices.getService(PackageManagerInternal.class);
732 ApplicationInfo info = pmInt.getApplicationInfo(packageName, flags,
733 callingUid, user.getIdentifier());
Kenny Guy77242752016-01-15 13:29:06 +0000734 return info;
735 } finally {
736 Binder.restoreCallingIdentity(ident);
737 }
738 }
739
Varun Shah2546cef2019-01-11 15:50:54 -0800740 @Override
741 public LauncherApps.AppUsageLimit getAppUsageLimit(String callingPackage,
742 String packageName, UserHandle user) {
743 verifyCallingPackage(callingPackage);
744 if (!canAccessProfile(user.getIdentifier(), "Cannot access usage limit")) {
745 return null;
746 }
747
748 final PackageManagerInternal pmi =
749 LocalServices.getService(PackageManagerInternal.class);
750 final ComponentName cn = pmi.getDefaultHomeActivity(user.getIdentifier());
751 if (!cn.getPackageName().equals(callingPackage)) {
752 throw new SecurityException("Caller is not the active launcher");
753 }
754
755 final UsageStatsManagerInternal.AppUsageLimitData data =
756 mUsageStatsManagerInternal.getAppUsageLimit(packageName, user);
757 if (data == null) {
758 return null;
759 }
760 return new LauncherApps.AppUsageLimit(
Varun Shah9c6f72b2019-01-25 21:13:56 -0800761 data.getTotalUsageLimit(), data.getUsageRemaining());
Varun Shah2546cef2019-01-11 15:50:54 -0800762 }
763
Makoto Onukide3c16c2017-01-26 11:39:31 -0800764 private void ensureShortcutPermission(@NonNull String callingPackage) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800765 verifyCallingPackage(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700766 if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700767 callingPackage, injectBinderCallingPid(), injectBinderCallingUid())) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800768 throw new SecurityException("Caller can't access shortcut information");
769 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800770 }
771
772 @Override
773 public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
Makoto Onuki99302b52017-03-29 12:42:26 -0700774 String packageName, List shortcutIds, ComponentName componentName, int flags,
775 UserHandle targetUser) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800776 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800777 if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800778 return new ParceledListSlice<>(Collections.EMPTY_LIST);
Makoto Onukiac214972016-04-04 10:19:45 -0700779 }
Makoto Onukiabe84422016-04-07 09:41:19 -0700780 if (shortcutIds != null && packageName == null) {
781 throw new IllegalArgumentException(
782 "To query by shortcut ID, package name must also be set");
783 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800784
Felipe Lemef93ce172016-06-13 14:19:40 -0700785 // TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below.
786 return new ParceledListSlice<>((List<ShortcutInfo>)
Makoto Onukid99c6f02016-03-28 11:02:54 -0700787 mShortcutServiceInternal.getShortcuts(getCallingUserId(),
Makoto Onukiabe84422016-04-07 09:41:19 -0700788 callingPackage, changedSince, packageName, shortcutIds,
Makoto Onuki634cecb2017-10-13 17:10:48 -0700789 componentName, flags, targetUser.getIdentifier(),
790 injectBinderCallingPid(), injectBinderCallingUid()));
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800791 }
792
793 @Override
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800794 public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800795 UserHandle targetUser) {
796 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800797 if (!canAccessProfile(targetUser.getIdentifier(), "Cannot pin shortcuts")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800798 return;
799 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800800
Makoto Onukid99c6f02016-03-28 11:02:54 -0700801 mShortcutServiceInternal.pinShortcuts(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800802 callingPackage, packageName, ids, targetUser.getIdentifier());
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800803 }
804
805 @Override
Makoto Onukiabe84422016-04-07 09:41:19 -0700806 public int getShortcutIconResId(String callingPackage, String packageName, String id,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800807 int targetUserId) {
808 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800809 if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
Makoto Onukiac214972016-04-04 10:19:45 -0700810 return 0;
811 }
Makoto Onuki55046222016-03-08 10:49:47 -0800812
Makoto Onukid99c6f02016-03-28 11:02:54 -0700813 return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800814 callingPackage, packageName, id, targetUserId);
Makoto Onuki55046222016-03-08 10:49:47 -0800815 }
816
817 @Override
Makoto Onukiabe84422016-04-07 09:41:19 -0700818 public ParcelFileDescriptor getShortcutIconFd(String callingPackage,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800819 String packageName, String id, int targetUserId) {
820 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800821 if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
Makoto Onukiac214972016-04-04 10:19:45 -0700822 return null;
823 }
Makoto Onuki55046222016-03-08 10:49:47 -0800824
Makoto Onukid99c6f02016-03-28 11:02:54 -0700825 return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800826 callingPackage, packageName, id, targetUserId);
Makoto Onuki55046222016-03-08 10:49:47 -0800827 }
828
829 @Override
Makoto Onukid99c6f02016-03-28 11:02:54 -0700830 public boolean hasShortcutHostPermission(String callingPackage) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800831 verifyCallingPackage(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700832 return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700833 callingPackage, injectBinderCallingPid(), injectBinderCallingUid());
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800834 }
835
836 @Override
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700837 public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800838 Rect sourceBounds, Bundle startActivityOptions, int targetUserId) {
Makoto Onukid99c6f02016-03-28 11:02:54 -0700839 verifyCallingPackage(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800840 if (!canAccessProfile(targetUserId, "Cannot start activity")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800841 return false;
842 }
Makoto Onukiac214972016-04-04 10:19:45 -0700843
Makoto Onukid99c6f02016-03-28 11:02:54 -0700844 // Even without the permission, pinned shortcuts are always launchable.
845 if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800846 callingPackage, packageName, shortcutId, targetUserId)) {
847 ensureShortcutPermission(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700848 }
849
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700850 final Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
Makoto Onuki634cecb2017-10-13 17:10:48 -0700851 getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId,
852 injectBinderCallingPid(), injectBinderCallingUid());
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700853 if (intents == null || intents.length == 0) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700854 return false;
Makoto Onuki43204b82016-03-08 16:16:44 -0800855 }
856 // Note the target activity doesn't have to be exported.
857
Makoto Onuki7e5c3e82016-07-22 11:57:05 -0700858 intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Makoto Onuki0eed4412016-07-21 11:21:59 -0700859 intents[0].setSourceBounds(sourceBounds);
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700860
861 return startShortcutIntentsAsPublisher(
Makoto Onukide3c16c2017-01-26 11:39:31 -0800862 intents, packageName, startActivityOptions, targetUserId);
Makoto Onukiea11db12016-06-24 15:17:44 -0700863 }
864
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700865 private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents,
Makoto Onukiea11db12016-06-24 15:17:44 -0700866 @NonNull String publisherPackage, Bundle startActivityOptions, int userId) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700867 final int code;
Makoto Onuki43204b82016-03-08 16:16:44 -0800868 try {
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700869 code = mActivityTaskManagerInternal.startActivitiesAsPackage(publisherPackage,
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700870 userId, intents, startActivityOptions);
Bryce Lee7f936862017-05-09 15:33:18 -0700871 if (ActivityManager.isStartResultSuccessful(code)) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700872 return true; // Success
873 } else {
874 Log.e(TAG, "Couldn't start activity, code=" + code);
Makoto Onukiea11db12016-06-24 15:17:44 -0700875 }
Bryce Lee7f936862017-05-09 15:33:18 -0700876 return false;
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700877 } catch (SecurityException e) {
878 if (DEBUG) {
879 Slog.d(TAG, "SecurityException while launching intent", e);
880 }
881 return false;
Makoto Onuki43204b82016-03-08 16:16:44 -0800882 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800883 }
884
Kenny Guy77242752016-01-15 13:29:06 +0000885 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800886 public boolean isActivityEnabled(
887 String callingPackage, ComponentName component, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700888 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800889 if (!canAccessProfile(user.getIdentifier(), "Cannot check component")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700890 return false;
Amith Yamasani4f582632014-02-19 14:31:52 -0800891 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800892
Todd Kennedy18211fd2017-06-06 09:15:46 -0700893 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700894 long ident = Binder.clearCallingIdentity();
895 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700896 final PackageManagerInternal pmInt =
897 LocalServices.getService(PackageManagerInternal.class);
898 ActivityInfo info = pmInt.getActivityInfo(component,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600899 PackageManager.MATCH_DIRECT_BOOT_AWARE
900 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700901 callingUid, user.getIdentifier());
Makoto Onuki516020a2019-01-28 14:16:42 -0800902 // Note we don't check "exported" because if the caller has the same UID as the
903 // callee's UID, it can still be launched.
904 // (If an app doesn't export a front door activity and causes issues with the
905 // launcher, that's just the app's bug.)
906 return info != null && info.isEnabled();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700907 } finally {
908 Binder.restoreCallingIdentity(ident);
909 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800910 }
911
Amith Yamasani4f582632014-02-19 14:31:52 -0800912 @Override
Jon Miranda2b340a22019-01-25 14:03:49 -0800913 public void startSessionDetailsActivityAsUser(IApplicationThread caller,
914 String callingPackage, SessionInfo sessionInfo, Rect sourceBounds,
915 Bundle opts, UserHandle userHandle) throws RemoteException {
916 int userId = userHandle.getIdentifier();
917 if (!canAccessProfile(userId, "Cannot start details activity")) {
918 return;
919 }
920
921 Intent i = new Intent(Intent.ACTION_VIEW)
922 .setData(new Uri.Builder()
923 .scheme("market")
924 .authority("details")
925 .appendQueryParameter("id", sessionInfo.appPackageName)
926 .build())
927 .putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
928 .authority(callingPackage).build());
929 i.setSourceBounds(sourceBounds);
930
931 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage, i, opts,
932 userId);
933 }
934
935 @Override
Makoto Onuki1a342742018-04-26 14:56:59 -0700936 public void startActivityAsUser(IApplicationThread caller, String callingPackage,
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800937 ComponentName component, Rect sourceBounds,
Amith Yamasanidf7db072014-06-01 10:41:13 -0700938 Bundle opts, UserHandle user) throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800939 if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800940 return;
941 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700942
943 Intent launchIntent = new Intent(Intent.ACTION_MAIN);
944 launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Makoto Onuki347a6bd2016-07-19 11:13:08 -0700945 launchIntent.setSourceBounds(sourceBounds);
946 launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
947 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Kenny Guy2df18922014-07-17 13:01:25 +0100948 launchIntent.setPackage(component.getPackageName());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700949
Makoto Onuki1a342742018-04-26 14:56:59 -0700950 boolean canLaunch = false;
951
Todd Kennedy18211fd2017-06-06 09:15:46 -0700952 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700953 long ident = Binder.clearCallingIdentity();
954 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700955 final PackageManagerInternal pmInt =
956 LocalServices.getService(PackageManagerInternal.class);
Kenny Guy2df18922014-07-17 13:01:25 +0100957 // Check that the component actually has Intent.CATEGORY_LAUCNCHER
958 // as calling startActivityAsUser ignores the category and just
959 // resolves based on the component if present.
Todd Kennedy18211fd2017-06-06 09:15:46 -0700960 List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600961 PackageManager.MATCH_DIRECT_BOOT_AWARE
962 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700963 callingUid, user.getIdentifier());
Kenny Guy2df18922014-07-17 13:01:25 +0100964 final int size = apps.size();
965 for (int i = 0; i < size; ++i) {
966 ActivityInfo activityInfo = apps.get(i).activityInfo;
967 if (activityInfo.packageName.equals(component.getPackageName()) &&
968 activityInfo.name.equals(component.getClassName())) {
Sunny Goyal06ef5af2018-10-16 15:32:41 -0700969 if (!activityInfo.exported) {
970 throw new SecurityException("Cannot launch non-exported components "
971 + component);
972 }
973
Kenny Guy2df18922014-07-17 13:01:25 +0100974 // Found an activity with category launcher that matches
975 // this component so ok to launch.
Tony Mak12917c62018-01-15 15:17:13 +0000976 launchIntent.setPackage(null);
Kenny Guy2df18922014-07-17 13:01:25 +0100977 launchIntent.setComponent(component);
Makoto Onuki1a342742018-04-26 14:56:59 -0700978 canLaunch = true;
979 break;
Kenny Guy2df18922014-07-17 13:01:25 +0100980 }
981 }
Makoto Onuki1a342742018-04-26 14:56:59 -0700982 if (!canLaunch) {
983 throw new SecurityException("Attempt to launch activity without "
984 + " category Intent.CATEGORY_LAUNCHER " + component);
985 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700986 } finally {
987 Binder.restoreCallingIdentity(ident);
988 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700989 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,
Makoto Onuki1a342742018-04-26 14:56:59 -0700990 launchIntent, opts, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700991 }
992
Kenny Guy466d2032014-07-23 12:23:35 +0100993 @Override
Makoto Onuki1a342742018-04-26 14:56:59 -0700994 public void showAppDetailsAsUser(IApplicationThread caller,
995 String callingPackage, ComponentName component,
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800996 Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800997 if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800998 return;
999 }
Kenny Guy466d2032014-07-23 12:23:35 +01001000
Makoto Onuki1a342742018-04-26 14:56:59 -07001001 final Intent intent;
Kenny Guy466d2032014-07-23 12:23:35 +01001002 long ident = Binder.clearCallingIdentity();
1003 try {
1004 String packageName = component.getPackageName();
Makoto Onuki1a342742018-04-26 14:56:59 -07001005 intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Kenny Guy466d2032014-07-23 12:23:35 +01001006 Uri.fromParts("package", packageName, null));
Winson369aad02016-02-17 10:35:47 -08001007 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Kenny Guy466d2032014-07-23 12:23:35 +01001008 intent.setSourceBounds(sourceBounds);
Kenny Guy466d2032014-07-23 12:23:35 +01001009 } finally {
1010 Binder.restoreCallingIdentity(ident);
1011 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001012 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,
Makoto Onuki1a342742018-04-26 14:56:59 -07001013 intent, opts, user.getIdentifier());
Kenny Guy466d2032014-07-23 12:23:35 +01001014 }
1015
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001016 /** Checks if user is a profile of or same as listeningUser.
1017 * and the user is enabled. */
Sunny Goyal145c8f82018-02-15 14:27:09 -08001018 private boolean isEnabledProfileOf(UserHandle listeningUser, UserHandle user,
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001019 String debugMsg) {
Sunny Goyal145c8f82018-02-15 14:27:09 -08001020 return mUserManagerInternal.isProfileAccessible(listeningUser.getIdentifier(),
1021 user.getIdentifier(), debugMsg, false);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001022 }
1023
Makoto Onukic5475d42016-03-25 10:54:07 -07001024 @VisibleForTesting
Makoto Onukiaa8b94a2016-03-17 13:14:05 -07001025 void postToPackageMonitorHandler(Runnable r) {
Makoto Onukic5475d42016-03-25 10:54:07 -07001026 mCallbackHandler.post(r);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001027 }
1028
Ricky Waie346a492019-01-21 14:54:32 +00001029 private class VouchesChangedMonitor extends PackageMonitor {
1030 @Override
1031 public void onPackageAdded(String packageName, int uid) {
1032 updateVouches(packageName, new UserHandle(getChangingUserId()));
1033 }
1034
1035 @Override
1036 public void onPackageModified(String packageName) {
1037 updateVouches(packageName, new UserHandle(getChangingUserId()));
1038 }
1039 }
1040
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001041 private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
Amith Yamasanidf7db072014-06-01 10:41:13 -07001042
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001043 // TODO Simplify with lambdas.
1044
Amith Yamasanidf7db072014-06-01 10:41:13 -07001045 @Override
1046 public void onPackageAdded(String packageName, int uid) {
1047 UserHandle user = new UserHandle(getChangingUserId());
1048 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001049 try {
1050 for (int i = 0; i < n; i++) {
1051 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1052 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001053 if (!isEnabledProfileOf(cookie.user, user, "onPackageAdded")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001054 try {
1055 listener.onPackageAdded(user, packageName);
1056 } catch (RemoteException re) {
1057 Slog.d(TAG, "Callback failed ", re);
1058 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001059 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001060 } finally {
1061 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001062 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001063
1064 super.onPackageAdded(packageName, uid);
1065 }
1066
1067 @Override
1068 public void onPackageRemoved(String packageName, int uid) {
1069 UserHandle user = new UserHandle(getChangingUserId());
1070 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001071 try {
1072 for (int i = 0; i < n; i++) {
1073 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1074 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001075 if (!isEnabledProfileOf(cookie.user, user, "onPackageRemoved")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001076 try {
1077 listener.onPackageRemoved(user, packageName);
1078 } catch (RemoteException re) {
1079 Slog.d(TAG, "Callback failed ", re);
1080 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001081 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001082 } finally {
1083 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001084 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001085
1086 super.onPackageRemoved(packageName, uid);
1087 }
1088
1089 @Override
1090 public void onPackageModified(String packageName) {
1091 UserHandle user = new UserHandle(getChangingUserId());
1092 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001093 try {
1094 for (int i = 0; i < n; i++) {
1095 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1096 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001097 if (!isEnabledProfileOf(cookie.user, user, "onPackageModified")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001098 try {
1099 listener.onPackageChanged(user, packageName);
1100 } catch (RemoteException re) {
1101 Slog.d(TAG, "Callback failed ", re);
1102 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001103 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001104 } finally {
1105 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001106 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001107
1108 super.onPackageModified(packageName);
1109 }
1110
1111 @Override
1112 public void onPackagesAvailable(String[] packages) {
1113 UserHandle user = new UserHandle(getChangingUserId());
1114 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001115 try {
1116 for (int i = 0; i < n; i++) {
1117 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1118 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001119 if (!isEnabledProfileOf(cookie.user, user, "onPackagesAvailable")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001120 try {
1121 listener.onPackagesAvailable(user, packages, isReplacing());
1122 } catch (RemoteException re) {
1123 Slog.d(TAG, "Callback failed ", re);
1124 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001125 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001126 } finally {
1127 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001128 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001129
1130 super.onPackagesAvailable(packages);
1131 }
1132
1133 @Override
1134 public void onPackagesUnavailable(String[] packages) {
1135 UserHandle user = new UserHandle(getChangingUserId());
1136 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001137 try {
1138 for (int i = 0; i < n; i++) {
1139 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1140 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001141 if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnavailable")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001142 try {
1143 listener.onPackagesUnavailable(user, packages, isReplacing());
1144 } catch (RemoteException re) {
1145 Slog.d(TAG, "Callback failed ", re);
1146 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001147 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001148 } finally {
1149 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001150 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001151
1152 super.onPackagesUnavailable(packages);
1153 }
1154
Kenny Guy77242752016-01-15 13:29:06 +00001155 @Override
Suprabh Shukla19b41f32018-03-26 22:35:13 -07001156 public void onPackagesSuspended(String[] packages, Bundle launcherExtras) {
Kenny Guy77242752016-01-15 13:29:06 +00001157 UserHandle user = new UserHandle(getChangingUserId());
1158 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001159 try {
1160 for (int i = 0; i < n; i++) {
1161 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1162 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001163 if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001164 try {
Suprabh Shukla19b41f32018-03-26 22:35:13 -07001165 listener.onPackagesSuspended(user, packages, launcherExtras);
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001166 } catch (RemoteException re) {
1167 Slog.d(TAG, "Callback failed ", re);
1168 }
Kenny Guy77242752016-01-15 13:29:06 +00001169 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001170 } finally {
1171 mListeners.finishBroadcast();
Kenny Guy77242752016-01-15 13:29:06 +00001172 }
Kenny Guy77242752016-01-15 13:29:06 +00001173
Suprabh Shukla19b41f32018-03-26 22:35:13 -07001174 super.onPackagesSuspended(packages, launcherExtras);
Kenny Guy77242752016-01-15 13:29:06 +00001175 }
1176
1177 @Override
1178 public void onPackagesUnsuspended(String[] packages) {
1179 UserHandle user = new UserHandle(getChangingUserId());
1180 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001181 try {
1182 for (int i = 0; i < n; i++) {
1183 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1184 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001185 if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnsuspended")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001186 try {
1187 listener.onPackagesUnsuspended(user, packages);
1188 } catch (RemoteException re) {
1189 Slog.d(TAG, "Callback failed ", re);
1190 }
Kenny Guy77242752016-01-15 13:29:06 +00001191 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001192 } finally {
1193 mListeners.finishBroadcast();
Kenny Guy77242752016-01-15 13:29:06 +00001194 }
Kenny Guy77242752016-01-15 13:29:06 +00001195
1196 super.onPackagesUnsuspended(packages);
1197 }
1198
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001199 @Override
1200 public void onShortcutChanged(@NonNull String packageName,
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001201 @UserIdInt int userId) {
Makoto Onukiaa8b94a2016-03-17 13:14:05 -07001202 postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId));
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001203 }
1204
1205 private void onShortcutChangedInner(@NonNull String packageName,
1206 @UserIdInt int userId) {
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001207 final int n = mListeners.beginBroadcast();
Makoto Onuki02f338e2016-07-29 09:40:40 -07001208 try {
1209 final UserHandle user = UserHandle.of(userId);
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001210
Makoto Onuki02f338e2016-07-29 09:40:40 -07001211 for (int i = 0; i < n; i++) {
1212 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1213 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001214 if (!isEnabledProfileOf(cookie.user, user, "onShortcutChanged")) continue;
Makoto Onuki2d5b4652016-03-11 16:09:54 -08001215
Makoto Onuki02f338e2016-07-29 09:40:40 -07001216 final int launcherUserId = cookie.user.getIdentifier();
Makoto Onukid99c6f02016-03-28 11:02:54 -07001217
Makoto Onuki02f338e2016-07-29 09:40:40 -07001218 // Make sure the caller has the permission.
1219 if (!mShortcutServiceInternal.hasShortcutHostPermission(
Makoto Onuki634cecb2017-10-13 17:10:48 -07001220 launcherUserId, cookie.packageName,
1221 cookie.callingPid, cookie.callingUid)) {
Makoto Onuki02f338e2016-07-29 09:40:40 -07001222 continue;
1223 }
1224 // Each launcher has a different set of pinned shortcuts, so we need to do a
1225 // query in here.
1226 // (As of now, only one launcher has the permission at a time, so it's bit
1227 // moot, but we may change the permission model eventually.)
1228 final List<ShortcutInfo> list =
1229 mShortcutServiceInternal.getShortcuts(launcherUserId,
1230 cookie.packageName,
1231 /* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
1232 /* component= */ null,
1233 ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
Makoto Onuki634cecb2017-10-13 17:10:48 -07001234 | ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED
1235 , userId, cookie.callingPid, cookie.callingUid);
Makoto Onuki02f338e2016-07-29 09:40:40 -07001236 try {
1237 listener.onShortcutChanged(user, packageName,
1238 new ParceledListSlice<>(list));
1239 } catch (RemoteException re) {
1240 Slog.d(TAG, "Callback failed ", re);
1241 }
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001242 }
Makoto Onuki02f338e2016-07-29 09:40:40 -07001243 } catch (RuntimeException e) {
1244 // When the user is locked we get IllegalState, so just catch all.
1245 Log.w(TAG, e.getMessage(), e);
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001246 } finally {
1247 mListeners.finishBroadcast();
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001248 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001249 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001250 }
1251
1252 class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> {
1253 @Override
1254 public void onCallbackDied(T callback, Object cookie) {
1255 checkCallbackCount();
1256 }
Amith Yamasani4f582632014-02-19 14:31:52 -08001257 }
1258 }
Nicolas Prevotb6830192015-06-26 13:45:12 -07001259}