blob: 05af13ab9eecfff84452fb9441997227c74e236f [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 }
Varun Shahe9abb752019-02-11 11:25:06 -0800747 if (!mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) {
748 throw new SecurityException("Caller is not the recents app");
Varun Shah2546cef2019-01-11 15:50:54 -0800749 }
750
751 final UsageStatsManagerInternal.AppUsageLimitData data =
752 mUsageStatsManagerInternal.getAppUsageLimit(packageName, user);
753 if (data == null) {
754 return null;
755 }
756 return new LauncherApps.AppUsageLimit(
Varun Shah9c6f72b2019-01-25 21:13:56 -0800757 data.getTotalUsageLimit(), data.getUsageRemaining());
Varun Shah2546cef2019-01-11 15:50:54 -0800758 }
759
Makoto Onukide3c16c2017-01-26 11:39:31 -0800760 private void ensureShortcutPermission(@NonNull String callingPackage) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800761 verifyCallingPackage(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700762 if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700763 callingPackage, injectBinderCallingPid(), injectBinderCallingUid())) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800764 throw new SecurityException("Caller can't access shortcut information");
765 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800766 }
767
768 @Override
769 public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
Makoto Onuki99302b52017-03-29 12:42:26 -0700770 String packageName, List shortcutIds, ComponentName componentName, int flags,
771 UserHandle targetUser) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800772 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800773 if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800774 return new ParceledListSlice<>(Collections.EMPTY_LIST);
Makoto Onukiac214972016-04-04 10:19:45 -0700775 }
Makoto Onukiabe84422016-04-07 09:41:19 -0700776 if (shortcutIds != null && packageName == null) {
777 throw new IllegalArgumentException(
778 "To query by shortcut ID, package name must also be set");
779 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800780
Felipe Lemef93ce172016-06-13 14:19:40 -0700781 // TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below.
782 return new ParceledListSlice<>((List<ShortcutInfo>)
Makoto Onukid99c6f02016-03-28 11:02:54 -0700783 mShortcutServiceInternal.getShortcuts(getCallingUserId(),
Makoto Onukiabe84422016-04-07 09:41:19 -0700784 callingPackage, changedSince, packageName, shortcutIds,
Makoto Onuki634cecb2017-10-13 17:10:48 -0700785 componentName, flags, targetUser.getIdentifier(),
786 injectBinderCallingPid(), injectBinderCallingUid()));
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800787 }
788
789 @Override
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800790 public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800791 UserHandle targetUser) {
792 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800793 if (!canAccessProfile(targetUser.getIdentifier(), "Cannot pin shortcuts")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800794 return;
795 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800796
Makoto Onukid99c6f02016-03-28 11:02:54 -0700797 mShortcutServiceInternal.pinShortcuts(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800798 callingPackage, packageName, ids, targetUser.getIdentifier());
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800799 }
800
801 @Override
Makoto Onukiabe84422016-04-07 09:41:19 -0700802 public int getShortcutIconResId(String callingPackage, String packageName, String id,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800803 int targetUserId) {
804 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800805 if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
Makoto Onukiac214972016-04-04 10:19:45 -0700806 return 0;
807 }
Makoto Onuki55046222016-03-08 10:49:47 -0800808
Makoto Onukid99c6f02016-03-28 11:02:54 -0700809 return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800810 callingPackage, packageName, id, targetUserId);
Makoto Onuki55046222016-03-08 10:49:47 -0800811 }
812
813 @Override
Makoto Onukiabe84422016-04-07 09:41:19 -0700814 public ParcelFileDescriptor getShortcutIconFd(String callingPackage,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800815 String packageName, String id, int targetUserId) {
816 ensureShortcutPermission(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800817 if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
Makoto Onukiac214972016-04-04 10:19:45 -0700818 return null;
819 }
Makoto Onuki55046222016-03-08 10:49:47 -0800820
Makoto Onukid99c6f02016-03-28 11:02:54 -0700821 return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800822 callingPackage, packageName, id, targetUserId);
Makoto Onuki55046222016-03-08 10:49:47 -0800823 }
824
825 @Override
Makoto Onukid99c6f02016-03-28 11:02:54 -0700826 public boolean hasShortcutHostPermission(String callingPackage) {
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800827 verifyCallingPackage(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700828 return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
Makoto Onuki634cecb2017-10-13 17:10:48 -0700829 callingPackage, injectBinderCallingPid(), injectBinderCallingUid());
Makoto Onuki2d5b4652016-03-11 16:09:54 -0800830 }
831
832 @Override
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700833 public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
Makoto Onukide3c16c2017-01-26 11:39:31 -0800834 Rect sourceBounds, Bundle startActivityOptions, int targetUserId) {
Makoto Onukid99c6f02016-03-28 11:02:54 -0700835 verifyCallingPackage(callingPackage);
Sunny Goyal145c8f82018-02-15 14:27:09 -0800836 if (!canAccessProfile(targetUserId, "Cannot start activity")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800837 return false;
838 }
Makoto Onukiac214972016-04-04 10:19:45 -0700839
Makoto Onukid99c6f02016-03-28 11:02:54 -0700840 // Even without the permission, pinned shortcuts are always launchable.
841 if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(),
Makoto Onukide3c16c2017-01-26 11:39:31 -0800842 callingPackage, packageName, shortcutId, targetUserId)) {
843 ensureShortcutPermission(callingPackage);
Makoto Onukid99c6f02016-03-28 11:02:54 -0700844 }
845
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700846 final Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
Makoto Onuki634cecb2017-10-13 17:10:48 -0700847 getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId,
848 injectBinderCallingPid(), injectBinderCallingUid());
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700849 if (intents == null || intents.length == 0) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700850 return false;
Makoto Onuki43204b82016-03-08 16:16:44 -0800851 }
852 // Note the target activity doesn't have to be exported.
853
Makoto Onuki7e5c3e82016-07-22 11:57:05 -0700854 intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Makoto Onuki0eed4412016-07-21 11:21:59 -0700855 intents[0].setSourceBounds(sourceBounds);
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700856
857 return startShortcutIntentsAsPublisher(
Makoto Onukide3c16c2017-01-26 11:39:31 -0800858 intents, packageName, startActivityOptions, targetUserId);
Makoto Onukiea11db12016-06-24 15:17:44 -0700859 }
860
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700861 private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents,
Makoto Onukiea11db12016-06-24 15:17:44 -0700862 @NonNull String publisherPackage, Bundle startActivityOptions, int userId) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700863 final int code;
Makoto Onuki43204b82016-03-08 16:16:44 -0800864 try {
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700865 code = mActivityTaskManagerInternal.startActivitiesAsPackage(publisherPackage,
Makoto Onuki440a1ea2016-07-20 14:21:18 -0700866 userId, intents, startActivityOptions);
Bryce Lee7f936862017-05-09 15:33:18 -0700867 if (ActivityManager.isStartResultSuccessful(code)) {
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700868 return true; // Success
869 } else {
870 Log.e(TAG, "Couldn't start activity, code=" + code);
Makoto Onukiea11db12016-06-24 15:17:44 -0700871 }
Bryce Lee7f936862017-05-09 15:33:18 -0700872 return false;
Makoto Onuki83f6d2d2016-07-11 14:30:19 -0700873 } catch (SecurityException e) {
874 if (DEBUG) {
875 Slog.d(TAG, "SecurityException while launching intent", e);
876 }
877 return false;
Makoto Onuki43204b82016-03-08 16:16:44 -0800878 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800879 }
880
Kenny Guy77242752016-01-15 13:29:06 +0000881 @Override
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800882 public boolean isActivityEnabled(
883 String callingPackage, ComponentName component, UserHandle user)
Amith Yamasanidf7db072014-06-01 10:41:13 -0700884 throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800885 if (!canAccessProfile(user.getIdentifier(), "Cannot check component")) {
Amith Yamasanidf7db072014-06-01 10:41:13 -0700886 return false;
Amith Yamasani4f582632014-02-19 14:31:52 -0800887 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800888
Todd Kennedy18211fd2017-06-06 09:15:46 -0700889 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700890 long ident = Binder.clearCallingIdentity();
891 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700892 final PackageManagerInternal pmInt =
893 LocalServices.getService(PackageManagerInternal.class);
894 ActivityInfo info = pmInt.getActivityInfo(component,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600895 PackageManager.MATCH_DIRECT_BOOT_AWARE
896 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700897 callingUid, user.getIdentifier());
Makoto Onuki516020a2019-01-28 14:16:42 -0800898 // Note we don't check "exported" because if the caller has the same UID as the
899 // callee's UID, it can still be launched.
900 // (If an app doesn't export a front door activity and causes issues with the
901 // launcher, that's just the app's bug.)
902 return info != null && info.isEnabled();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700903 } finally {
904 Binder.restoreCallingIdentity(ident);
905 }
Amith Yamasani4f582632014-02-19 14:31:52 -0800906 }
907
Amith Yamasani4f582632014-02-19 14:31:52 -0800908 @Override
Jon Miranda2b340a22019-01-25 14:03:49 -0800909 public void startSessionDetailsActivityAsUser(IApplicationThread caller,
910 String callingPackage, SessionInfo sessionInfo, Rect sourceBounds,
911 Bundle opts, UserHandle userHandle) throws RemoteException {
912 int userId = userHandle.getIdentifier();
913 if (!canAccessProfile(userId, "Cannot start details activity")) {
914 return;
915 }
916
917 Intent i = new Intent(Intent.ACTION_VIEW)
918 .setData(new Uri.Builder()
919 .scheme("market")
920 .authority("details")
921 .appendQueryParameter("id", sessionInfo.appPackageName)
922 .build())
923 .putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
924 .authority(callingPackage).build());
925 i.setSourceBounds(sourceBounds);
926
927 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage, i, opts,
928 userId);
929 }
930
931 @Override
Makoto Onuki1a342742018-04-26 14:56:59 -0700932 public void startActivityAsUser(IApplicationThread caller, String callingPackage,
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800933 ComponentName component, Rect sourceBounds,
Amith Yamasanidf7db072014-06-01 10:41:13 -0700934 Bundle opts, UserHandle user) throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800935 if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800936 return;
937 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700938
939 Intent launchIntent = new Intent(Intent.ACTION_MAIN);
940 launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Makoto Onuki347a6bd2016-07-19 11:13:08 -0700941 launchIntent.setSourceBounds(sourceBounds);
942 launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
943 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Kenny Guy2df18922014-07-17 13:01:25 +0100944 launchIntent.setPackage(component.getPackageName());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700945
Makoto Onuki1a342742018-04-26 14:56:59 -0700946 boolean canLaunch = false;
947
Todd Kennedy18211fd2017-06-06 09:15:46 -0700948 final int callingUid = injectBinderCallingUid();
Amith Yamasanidf7db072014-06-01 10:41:13 -0700949 long ident = Binder.clearCallingIdentity();
950 try {
Todd Kennedy18211fd2017-06-06 09:15:46 -0700951 final PackageManagerInternal pmInt =
952 LocalServices.getService(PackageManagerInternal.class);
Kenny Guy2df18922014-07-17 13:01:25 +0100953 // Check that the component actually has Intent.CATEGORY_LAUCNCHER
954 // as calling startActivityAsUser ignores the category and just
955 // resolves based on the component if present.
Todd Kennedy18211fd2017-06-06 09:15:46 -0700956 List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent,
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600957 PackageManager.MATCH_DIRECT_BOOT_AWARE
958 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Todd Kennedy18211fd2017-06-06 09:15:46 -0700959 callingUid, user.getIdentifier());
Kenny Guy2df18922014-07-17 13:01:25 +0100960 final int size = apps.size();
961 for (int i = 0; i < size; ++i) {
962 ActivityInfo activityInfo = apps.get(i).activityInfo;
963 if (activityInfo.packageName.equals(component.getPackageName()) &&
964 activityInfo.name.equals(component.getClassName())) {
Sunny Goyal06ef5af2018-10-16 15:32:41 -0700965 if (!activityInfo.exported) {
966 throw new SecurityException("Cannot launch non-exported components "
967 + component);
968 }
969
Kenny Guy2df18922014-07-17 13:01:25 +0100970 // Found an activity with category launcher that matches
971 // this component so ok to launch.
Tony Mak12917c62018-01-15 15:17:13 +0000972 launchIntent.setPackage(null);
Kenny Guy2df18922014-07-17 13:01:25 +0100973 launchIntent.setComponent(component);
Makoto Onuki1a342742018-04-26 14:56:59 -0700974 canLaunch = true;
975 break;
Kenny Guy2df18922014-07-17 13:01:25 +0100976 }
977 }
Makoto Onuki1a342742018-04-26 14:56:59 -0700978 if (!canLaunch) {
979 throw new SecurityException("Attempt to launch activity without "
980 + " category Intent.CATEGORY_LAUNCHER " + component);
981 }
Amith Yamasanidf7db072014-06-01 10:41:13 -0700982 } finally {
983 Binder.restoreCallingIdentity(ident);
984 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700985 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,
Makoto Onuki1a342742018-04-26 14:56:59 -0700986 launchIntent, opts, user.getIdentifier());
Amith Yamasanidf7db072014-06-01 10:41:13 -0700987 }
988
Kenny Guy466d2032014-07-23 12:23:35 +0100989 @Override
Makoto Onuki1a342742018-04-26 14:56:59 -0700990 public void showAppDetailsAsUser(IApplicationThread caller,
991 String callingPackage, ComponentName component,
Makoto Onuki3a2541e2017-01-24 09:00:15 -0800992 Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {
Sunny Goyal145c8f82018-02-15 14:27:09 -0800993 if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) {
Makoto Onukide3c16c2017-01-26 11:39:31 -0800994 return;
995 }
Kenny Guy466d2032014-07-23 12:23:35 +0100996
Makoto Onuki1a342742018-04-26 14:56:59 -0700997 final Intent intent;
Kenny Guy466d2032014-07-23 12:23:35 +0100998 long ident = Binder.clearCallingIdentity();
999 try {
1000 String packageName = component.getPackageName();
Makoto Onuki1a342742018-04-26 14:56:59 -07001001 intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Kenny Guy466d2032014-07-23 12:23:35 +01001002 Uri.fromParts("package", packageName, null));
Winson369aad02016-02-17 10:35:47 -08001003 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Kenny Guy466d2032014-07-23 12:23:35 +01001004 intent.setSourceBounds(sourceBounds);
Kenny Guy466d2032014-07-23 12:23:35 +01001005 } finally {
1006 Binder.restoreCallingIdentity(ident);
1007 }
Wale Ogunwale6767eae2018-05-03 15:52:51 -07001008 mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,
Makoto Onuki1a342742018-04-26 14:56:59 -07001009 intent, opts, user.getIdentifier());
Kenny Guy466d2032014-07-23 12:23:35 +01001010 }
1011
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001012 /** Checks if user is a profile of or same as listeningUser.
1013 * and the user is enabled. */
Sunny Goyal145c8f82018-02-15 14:27:09 -08001014 private boolean isEnabledProfileOf(UserHandle listeningUser, UserHandle user,
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001015 String debugMsg) {
Sunny Goyal145c8f82018-02-15 14:27:09 -08001016 return mUserManagerInternal.isProfileAccessible(listeningUser.getIdentifier(),
1017 user.getIdentifier(), debugMsg, false);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001018 }
1019
Makoto Onukic5475d42016-03-25 10:54:07 -07001020 @VisibleForTesting
Makoto Onukiaa8b94a2016-03-17 13:14:05 -07001021 void postToPackageMonitorHandler(Runnable r) {
Makoto Onukic5475d42016-03-25 10:54:07 -07001022 mCallbackHandler.post(r);
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001023 }
1024
Ricky Waie346a492019-01-21 14:54:32 +00001025 private class VouchesChangedMonitor extends PackageMonitor {
1026 @Override
1027 public void onPackageAdded(String packageName, int uid) {
1028 updateVouches(packageName, new UserHandle(getChangingUserId()));
1029 }
1030
1031 @Override
1032 public void onPackageModified(String packageName) {
1033 updateVouches(packageName, new UserHandle(getChangingUserId()));
1034 }
1035 }
1036
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001037 private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
Amith Yamasanidf7db072014-06-01 10:41:13 -07001038
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001039 // TODO Simplify with lambdas.
1040
Amith Yamasanidf7db072014-06-01 10:41:13 -07001041 @Override
1042 public void onPackageAdded(String packageName, int uid) {
1043 UserHandle user = new UserHandle(getChangingUserId());
1044 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001045 try {
1046 for (int i = 0; i < n; i++) {
1047 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1048 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001049 if (!isEnabledProfileOf(cookie.user, user, "onPackageAdded")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001050 try {
1051 listener.onPackageAdded(user, packageName);
1052 } catch (RemoteException re) {
1053 Slog.d(TAG, "Callback failed ", re);
1054 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001055 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001056 } finally {
1057 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001058 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001059
1060 super.onPackageAdded(packageName, uid);
1061 }
1062
1063 @Override
1064 public void onPackageRemoved(String packageName, int uid) {
1065 UserHandle user = new UserHandle(getChangingUserId());
1066 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001067 try {
1068 for (int i = 0; i < n; i++) {
1069 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1070 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001071 if (!isEnabledProfileOf(cookie.user, user, "onPackageRemoved")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001072 try {
1073 listener.onPackageRemoved(user, packageName);
1074 } catch (RemoteException re) {
1075 Slog.d(TAG, "Callback failed ", re);
1076 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001077 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001078 } finally {
1079 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001080 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001081
1082 super.onPackageRemoved(packageName, uid);
1083 }
1084
1085 @Override
1086 public void onPackageModified(String packageName) {
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, "onPackageModified")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001094 try {
1095 listener.onPackageChanged(user, packageName);
1096 } catch (RemoteException re) {
1097 Slog.d(TAG, "Callback failed ", re);
1098 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001099 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001100 } finally {
1101 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001102 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001103
1104 super.onPackageModified(packageName);
1105 }
1106
1107 @Override
1108 public void onPackagesAvailable(String[] packages) {
1109 UserHandle user = new UserHandle(getChangingUserId());
1110 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001111 try {
1112 for (int i = 0; i < n; i++) {
1113 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1114 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001115 if (!isEnabledProfileOf(cookie.user, user, "onPackagesAvailable")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001116 try {
1117 listener.onPackagesAvailable(user, packages, isReplacing());
1118 } catch (RemoteException re) {
1119 Slog.d(TAG, "Callback failed ", re);
1120 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001121 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001122 } finally {
1123 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001124 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001125
1126 super.onPackagesAvailable(packages);
1127 }
1128
1129 @Override
1130 public void onPackagesUnavailable(String[] packages) {
1131 UserHandle user = new UserHandle(getChangingUserId());
1132 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001133 try {
1134 for (int i = 0; i < n; i++) {
1135 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1136 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001137 if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnavailable")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001138 try {
1139 listener.onPackagesUnavailable(user, packages, isReplacing());
1140 } catch (RemoteException re) {
1141 Slog.d(TAG, "Callback failed ", re);
1142 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001143 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001144 } finally {
1145 mListeners.finishBroadcast();
Amith Yamasanidf7db072014-06-01 10:41:13 -07001146 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001147
1148 super.onPackagesUnavailable(packages);
1149 }
1150
Kenny Guy77242752016-01-15 13:29:06 +00001151 @Override
Suprabh Shukla19b41f32018-03-26 22:35:13 -07001152 public void onPackagesSuspended(String[] packages, Bundle launcherExtras) {
Kenny Guy77242752016-01-15 13:29:06 +00001153 UserHandle user = new UserHandle(getChangingUserId());
1154 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001155 try {
1156 for (int i = 0; i < n; i++) {
1157 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1158 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001159 if (!isEnabledProfileOf(cookie.user, user, "onPackagesSuspended")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001160 try {
Suprabh Shukla19b41f32018-03-26 22:35:13 -07001161 listener.onPackagesSuspended(user, packages, launcherExtras);
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001162 } catch (RemoteException re) {
1163 Slog.d(TAG, "Callback failed ", re);
1164 }
Kenny Guy77242752016-01-15 13:29:06 +00001165 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001166 } finally {
1167 mListeners.finishBroadcast();
Kenny Guy77242752016-01-15 13:29:06 +00001168 }
Kenny Guy77242752016-01-15 13:29:06 +00001169
Suprabh Shukla19b41f32018-03-26 22:35:13 -07001170 super.onPackagesSuspended(packages, launcherExtras);
Kenny Guy77242752016-01-15 13:29:06 +00001171 }
1172
1173 @Override
1174 public void onPackagesUnsuspended(String[] packages) {
1175 UserHandle user = new UserHandle(getChangingUserId());
1176 final int n = mListeners.beginBroadcast();
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001177 try {
1178 for (int i = 0; i < n; i++) {
1179 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1180 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001181 if (!isEnabledProfileOf(cookie.user, user, "onPackagesUnsuspended")) continue;
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001182 try {
1183 listener.onPackagesUnsuspended(user, packages);
1184 } catch (RemoteException re) {
1185 Slog.d(TAG, "Callback failed ", re);
1186 }
Kenny Guy77242752016-01-15 13:29:06 +00001187 }
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001188 } finally {
1189 mListeners.finishBroadcast();
Kenny Guy77242752016-01-15 13:29:06 +00001190 }
Kenny Guy77242752016-01-15 13:29:06 +00001191
1192 super.onPackagesUnsuspended(packages);
1193 }
1194
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001195 @Override
1196 public void onShortcutChanged(@NonNull String packageName,
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001197 @UserIdInt int userId) {
Makoto Onukiaa8b94a2016-03-17 13:14:05 -07001198 postToPackageMonitorHandler(() -> onShortcutChangedInner(packageName, userId));
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001199 }
1200
1201 private void onShortcutChangedInner(@NonNull String packageName,
1202 @UserIdInt int userId) {
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001203 final int n = mListeners.beginBroadcast();
Makoto Onuki02f338e2016-07-29 09:40:40 -07001204 try {
1205 final UserHandle user = UserHandle.of(userId);
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001206
Makoto Onuki02f338e2016-07-29 09:40:40 -07001207 for (int i = 0; i < n; i++) {
1208 IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
1209 BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
Sunny Goyal145c8f82018-02-15 14:27:09 -08001210 if (!isEnabledProfileOf(cookie.user, user, "onShortcutChanged")) continue;
Makoto Onuki2d5b4652016-03-11 16:09:54 -08001211
Makoto Onuki02f338e2016-07-29 09:40:40 -07001212 final int launcherUserId = cookie.user.getIdentifier();
Makoto Onukid99c6f02016-03-28 11:02:54 -07001213
Makoto Onuki02f338e2016-07-29 09:40:40 -07001214 // Make sure the caller has the permission.
1215 if (!mShortcutServiceInternal.hasShortcutHostPermission(
Makoto Onuki634cecb2017-10-13 17:10:48 -07001216 launcherUserId, cookie.packageName,
1217 cookie.callingPid, cookie.callingUid)) {
Makoto Onuki02f338e2016-07-29 09:40:40 -07001218 continue;
1219 }
1220 // Each launcher has a different set of pinned shortcuts, so we need to do a
1221 // query in here.
1222 // (As of now, only one launcher has the permission at a time, so it's bit
1223 // moot, but we may change the permission model eventually.)
1224 final List<ShortcutInfo> list =
1225 mShortcutServiceInternal.getShortcuts(launcherUserId,
1226 cookie.packageName,
1227 /* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
1228 /* component= */ null,
1229 ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
Makoto Onuki634cecb2017-10-13 17:10:48 -07001230 | ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED
1231 , userId, cookie.callingPid, cookie.callingUid);
Makoto Onuki02f338e2016-07-29 09:40:40 -07001232 try {
1233 listener.onShortcutChanged(user, packageName,
1234 new ParceledListSlice<>(list));
1235 } catch (RemoteException re) {
1236 Slog.d(TAG, "Callback failed ", re);
1237 }
Makoto Onuki4dbe0de2016-03-14 17:31:49 -07001238 }
Makoto Onuki02f338e2016-07-29 09:40:40 -07001239 } catch (RuntimeException e) {
1240 // When the user is locked we get IllegalState, so just catch all.
1241 Log.w(TAG, e.getMessage(), e);
Makoto Onuki7bdb9ce2016-09-15 12:52:57 -07001242 } finally {
1243 mListeners.finishBroadcast();
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001244 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001245 }
Amith Yamasanidf7db072014-06-01 10:41:13 -07001246 }
1247
1248 class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> {
1249 @Override
1250 public void onCallbackDied(T callback, Object cookie) {
1251 checkCallbackCount();
1252 }
Amith Yamasani4f582632014-02-19 14:31:52 -08001253 }
1254 }
Nicolas Prevotb6830192015-06-26 13:45:12 -07001255}