LauncherAppsService.java revision 5504622fb01ab9774b5e73d05f86ee03a8b68ab7
14f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/*
24f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Copyright (C) 2014 The Android Open Source Project
34f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani *
44f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
54f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * you may not use this file except in compliance with the License.
64f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * You may obtain a copy of the License at
74f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani *
84f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
94f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani *
104f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Unless required by applicable law or agreed to in writing, software
114f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
124f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * See the License for the specific language governing permissions and
144f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * limitations under the License.
154f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */
164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasanipackage com.android.server.pm;
184f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
196f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.annotation.NonNull;
2043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onukiimport android.annotation.Nullable;
216f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.annotation.UserIdInt;
2253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.app.AppGlobals;
234f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.ComponentName;
244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.Context;
254f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.Intent;
2653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.ActivityInfo;
27772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guyimport android.content.pm.ApplicationInfo;
284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.ILauncherApps;
294f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.IOnAppsChangedListener;
3053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.IPackageManager;
3153fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guyimport android.content.pm.PackageInfo;
32cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkeyimport android.content.pm.PackageManager;
336f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.PackageManager.NameNotFoundException;
346cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyalimport android.content.pm.ParceledListSlice;
354f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.ResolveInfo;
366f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutInfo;
376f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutServiceInternal;
386f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
394f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.UserInfo;
404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.graphics.Rect;
41466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guyimport android.net.Uri;
424f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Binder;
434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Bundle;
444f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.IInterface;
455504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onukiimport android.os.ParcelFileDescriptor;
464f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteCallbackList;
474f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteException;
484f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserHandle;
494f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserManager;
50466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guyimport android.provider.Settings;
51932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasaniimport android.util.Log;
524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.util.Slog;
534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport com.android.internal.content.PackageMonitor;
556f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport com.android.internal.util.Preconditions;
566f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onukiimport com.android.server.LocalServices;
57df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasaniimport com.android.server.SystemService;
584f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
594f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.List;
604f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
614f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/**
624f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Service that manages requests and callbacks for launchers that support
636f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki * managed profiles.
644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */
65df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasanipublic class LauncherAppsService extends SystemService {
66df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
67df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani    private final LauncherAppsImpl mLauncherAppsImpl;
684f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public LauncherAppsService(Context context) {
70df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        super(context);
71df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        mLauncherAppsImpl = new LauncherAppsImpl(context);
724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    @Override
75df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani    public void onStart() {
76df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl);
77df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani    }
78df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
796f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki    static class LauncherAppsImpl extends ILauncherApps.Stub {
80df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private static final boolean DEBUG = false;
81df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private static final String TAG = "LauncherAppsService";
82df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private final Context mContext;
83df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private final PackageManager mPm;
84df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private final UserManager mUm;
856f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        private final ShortcutServiceInternal mShortcutServiceInternal;
86df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private final PackageCallbackList<IOnAppsChangedListener> mListeners
87df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                = new PackageCallbackList<IOnAppsChangedListener>();
88df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
896f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
90df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
91df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        public LauncherAppsImpl(Context context) {
92df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            mContext = context;
93df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            mPm = mContext.getPackageManager();
94df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
956f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            mShortcutServiceInternal = Preconditions.checkNotNull(
966f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    LocalServices.getService(ShortcutServiceInternal.class));
976f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            mShortcutServiceInternal.addListener(mPackageMonitor);
98df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        }
99df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
100df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        /*
101df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         * @see android.content.pm.ILauncherApps#addOnAppsChangedListener(
102df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         *          android.content.pm.IOnAppsChangedListener)
103df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         */
104df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        @Override
105df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        public void addOnAppsChangedListener(IOnAppsChangedListener listener) throws RemoteException {
106df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            synchronized (mListeners) {
107932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani                if (DEBUG) {
108df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    Log.d(TAG, "Adding listener from " + Binder.getCallingUserHandle());
109932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani                }
110df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                if (mListeners.getRegisteredCallbackCount() == 0) {
111df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    if (DEBUG) {
112df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        Log.d(TAG, "Starting package monitoring");
113df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    }
114df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    startWatchingPackageBroadcasts();
115df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
116df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                mListeners.unregister(listener);
117df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                mListeners.register(listener, Binder.getCallingUserHandle());
1184f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
1194f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1204f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
121df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        /*
122df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener(
123df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         *          android.content.pm.IOnAppsChangedListener)
124df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         */
125df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        @Override
126df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        public void removeOnAppsChangedListener(IOnAppsChangedListener listener)
127df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                throws RemoteException {
128df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            synchronized (mListeners) {
129df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                if (DEBUG) {
130df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    Log.d(TAG, "Removing listener from " + Binder.getCallingUserHandle());
131df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
132df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                mListeners.unregister(listener);
133df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                if (mListeners.getRegisteredCallbackCount() == 0) {
134df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    stopWatchingPackageBroadcasts();
135df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
1364f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
1374f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1384f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
139df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        /**
140df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         * Register a receiver to watch for package broadcasts
141df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         */
142df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private void startWatchingPackageBroadcasts() {
143df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            mPackageMonitor.register(mContext, null, UserHandle.ALL, true);
144932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani        }
1454f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
146df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        /**
147df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         * Unregister package broadcast receiver
148df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         */
149df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private void stopWatchingPackageBroadcasts() {
150932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani            if (DEBUG) {
151df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                Log.d(TAG, "Stopped watching for packages");
1524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
153df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            mPackageMonitor.unregister();
1544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
156df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        void checkCallbackCount() {
157df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            synchronized (mListeners) {
158df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                if (DEBUG) {
159df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    Log.d(TAG, "Callback count = " + mListeners.getRegisteredCallbackCount());
160df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
161df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                if (mListeners.getRegisteredCallbackCount() == 0) {
162df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    stopWatchingPackageBroadcasts();
163df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
1644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
1654f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
167df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        /**
168df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         * Checks if the caller is in the same group as the userToCheck.
169df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         */
170df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private void ensureInUserProfiles(UserHandle userToCheck, String message) {
171df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            final int callingUserId = UserHandle.getCallingUserId();
172df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            final int targetUserId = userToCheck.getIdentifier();
173cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina
174df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            if (targetUserId == callingUserId) return;
1754f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
176df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            long ident = Binder.clearCallingIdentity();
177df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            try {
178df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
179df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                UserInfo targetUserInfo = mUm.getUserInfo(targetUserId);
180df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                if (targetUserInfo == null
181df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        || targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID
182df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        || targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) {
183df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    throw new SecurityException(message);
184df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
185df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            } finally {
186df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                Binder.restoreCallingIdentity(ident);
187df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
188cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina        }
1894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
1906f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        private void verifyCallingPackage(String callingPackage) {
1916f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            int packageUid = -1;
1926f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            try {
1936f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                packageUid = mPm.getPackageUid(callingPackage,
1946f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE
1956f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                                | PackageManager.MATCH_UNINSTALLED_PACKAGES);
1966f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            } catch (NameNotFoundException e) {
1976f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                Log.e(TAG, "Package not found: " + callingPackage);
1986f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            }
1996f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            if (packageUid != Binder.getCallingUid()) {
2006f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                throw new SecurityException("Calling package name mismatch");
2016f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            }
2026f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        }
2036f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
204df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        /**
205df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         * Checks if the user is enabled.
206df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani         */
207df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        private boolean isUserEnabled(UserHandle user) {
208df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            long ident = Binder.clearCallingIdentity();
209df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            try {
210df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                UserInfo targetUserInfo = mUm.getUserInfo(user.getIdentifier());
211df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                return targetUserInfo != null && targetUserInfo.isEnabled();
212df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            } finally {
213df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                Binder.restoreCallingIdentity(ident);
214df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
2154f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
2164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
217df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        @Override
2186cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal        public ParceledListSlice<ResolveInfo> getLauncherActivities(String packageName, UserHandle user)
219df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                throws RemoteException {
220df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            ensureInUserProfiles(user, "Cannot retrieve activities for unrelated profile " + user);
221df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            if (!isUserEnabled(user)) {
2226cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal                return null;
223df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
224cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina
225df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
226df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
227df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            mainIntent.setPackage(packageName);
228df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            long ident = Binder.clearCallingIdentity();
229df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            try {
230cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey                List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent,
231b1b302660cf5b1b1c5b342cc90eca93b8f66890cKenny Guy                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
2326cbc2fec91c8eae62b0ed578523af4f9765f9c17Sunny Goyal                return new ParceledListSlice<>(apps);
233df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            } finally {
234df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                Binder.restoreCallingIdentity(ident);
235df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
23653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        }
23753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy
238df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        @Override
239df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        public ResolveInfo resolveActivity(Intent intent, UserHandle user)
240df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                throws RemoteException {
241df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            ensureInUserProfiles(user, "Cannot resolve activity for unrelated profile " + user);
242df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            if (!isUserEnabled(user)) {
243df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                return null;
244df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
245cea2978737146485b88f06b24b5df5656f9586e1Alexandra Gherghina
246df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            long ident = Binder.clearCallingIdentity();
247df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            try {
248cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey                ResolveInfo app = mPm.resolveActivityAsUser(intent,
249b1b302660cf5b1b1c5b342cc90eca93b8f66890cKenny Guy                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
250df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                return app;
251df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            } finally {
252df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                Binder.restoreCallingIdentity(ident);
253df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
25453fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        }
25553fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy
256df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        @Override
257df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        public boolean isPackageEnabled(String packageName, UserHandle user)
258df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                throws RemoteException {
259df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user);
260df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            if (!isUserEnabled(user)) {
261df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                return false;
262df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
2634f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
264df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            long ident = Binder.clearCallingIdentity();
265df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            try {
266df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                IPackageManager pm = AppGlobals.getPackageManager();
267cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey                PackageInfo info = pm.getPackageInfo(packageName,
268b1b302660cf5b1b1c5b342cc90eca93b8f66890cKenny Guy                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
269df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                return info != null && info.applicationInfo.enabled;
270df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            } finally {
271df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                Binder.restoreCallingIdentity(ident);
272df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
2734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
2744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
275df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        @Override
276772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy        public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user)
277772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                throws RemoteException {
278772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user);
279772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            if (!isUserEnabled(user)) {
280772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                return null;
281772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            }
282772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy
283772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            long ident = Binder.clearCallingIdentity();
284772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            try {
285772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                IPackageManager pm = AppGlobals.getPackageManager();
286772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                ApplicationInfo info = pm.getApplicationInfo(packageName, flags,
287772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                        user.getIdentifier());
288772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                return info;
289772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            } finally {
290772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                Binder.restoreCallingIdentity(ident);
291772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            }
292772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy        }
293772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy
2946f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        private void enforceShortcutPermission(UserHandle user) {
2956f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user);
2966f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            // STOPSHIP Implement it
2976f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        }
2986f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
2996f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        @Override
3006f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
3016f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                String packageName, ComponentName componentName, int flags, UserHandle user)
3026f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                throws RemoteException {
3036f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            enforceShortcutPermission(user);
3046f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            verifyCallingPackage(callingPackage);
3056f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
3066f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            return new ParceledListSlice<>(
3076f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    mShortcutServiceInternal.getShortcuts(callingPackage, changedSince, packageName,
3086f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    componentName, flags, user.getIdentifier()));
3096f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        }
3106f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
3116f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        @Override
3126f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        public ParceledListSlice getShortcutInfo(String callingPackage, String packageName,
3136f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                List<String> ids, UserHandle user) throws RemoteException {
3146f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            enforceShortcutPermission(user);
3156f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            verifyCallingPackage(callingPackage);
3166f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
3176f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            return new ParceledListSlice<>(
3186f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    mShortcutServiceInternal.getShortcutInfo(callingPackage, packageName,
3196f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    ids, user.getIdentifier()));
3206f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        }
3216f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
3226f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        @Override
3236f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
3246f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                UserHandle user) throws RemoteException {
3256f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            enforceShortcutPermission(user);
3266f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            verifyCallingPackage(callingPackage);
3276f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
3286f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            mShortcutServiceInternal.pinShortcuts(callingPackage, packageName,
3296f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    ids, user.getIdentifier());
3306f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        }
3316f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
3326f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        @Override
3335504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki        public int getShortcutIconResId(String callingPackage, ShortcutInfo shortcut,
3345504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki                UserHandle user) {
3355504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki            enforceShortcutPermission(user);
3365504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki            verifyCallingPackage(callingPackage);
3375504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki
3385504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki            return mShortcutServiceInternal.getShortcutIconResId(callingPackage, shortcut,
3395504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki                    user.getIdentifier());
3405504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki        }
3415504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki
3425504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki        @Override
3435504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki        public ParcelFileDescriptor getShortcutIconFd(String callingPackage, ShortcutInfo shortcut,
3445504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki                UserHandle user) {
3455504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki            enforceShortcutPermission(user);
3465504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki            verifyCallingPackage(callingPackage);
3475504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki
3485504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki            return mShortcutServiceInternal.getShortcutIconFd(callingPackage, shortcut,
3495504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki                    user.getIdentifier());
3505504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki        }
3515504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki
3525504622fb01ab9774b5e73d05f86ee03a8b68ab7Makoto Onuki        @Override
35343204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki        public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
35443204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki                Rect sourceBounds, Bundle startActivityOptions, UserHandle user)
35543204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki                throws RemoteException {
3566f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            enforceShortcutPermission(user);
3576f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            verifyCallingPackage(callingPackage);
3586f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
3596f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            final Intent intent = mShortcutServiceInternal.createShortcutIntent(callingPackage,
36043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki                    packageName, shortcutId, user.getIdentifier());
36143204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            if (intent == null) {
36243204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki                return false;
36343204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            }
36443204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            // Note the target activity doesn't have to be exported.
36543204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki
36643204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            intent.setSourceBounds(sourceBounds);
36743204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            prepareIntentForLaunch(intent, sourceBounds);
36843204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki
36943204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            final long ident = Binder.clearCallingIdentity();
37043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            try {
37143204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki                mContext.startActivityAsUser(intent, startActivityOptions, user);
37243204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            } finally {
37343204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki                Binder.restoreCallingIdentity(ident);
37443204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            }
37543204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            return true;
3766f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        }
3776f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
378772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy        @Override
379df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        public boolean isActivityEnabled(ComponentName component, UserHandle user)
380df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                throws RemoteException {
381df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            ensureInUserProfiles(user, "Cannot check component for unrelated profile " + user);
382df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            if (!isUserEnabled(user)) {
383df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                return false;
384932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani            }
385df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
386932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani            long ident = Binder.clearCallingIdentity();
387932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani            try {
388df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                IPackageManager pm = AppGlobals.getPackageManager();
389cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey                ActivityInfo info = pm.getActivityInfo(component,
390b1b302660cf5b1b1c5b342cc90eca93b8f66890cKenny Guy                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
391dcf21d15456e5aca28d063aea73139e30842e6d1Winson Chung                return info != null;
392932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani            } finally {
393932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani                Binder.restoreCallingIdentity(ident);
394932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani            }
395932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani        }
396932249db930d78131c4314ff46ec5fca76cb46cdAmith Yamasani
3974f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
398df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        public void startActivityAsUser(ComponentName component, Rect sourceBounds,
399df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                Bundle opts, UserHandle user) throws RemoteException {
400df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user);
401df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            if (!isUserEnabled(user)) {
402df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                throw new IllegalStateException("Cannot start activity for disabled profile "  + user);
4034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
4044f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
405df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            Intent launchIntent = new Intent(Intent.ACTION_MAIN);
406df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
40743204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            prepareIntentForLaunch(launchIntent, sourceBounds);
4082df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy            launchIntent.setPackage(component.getPackageName());
409df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
410df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            long ident = Binder.clearCallingIdentity();
411df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            try {
4122df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                IPackageManager pm = AppGlobals.getPackageManager();
413cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey                ActivityInfo info = pm.getActivityInfo(component,
414b1b302660cf5b1b1c5b342cc90eca93b8f66890cKenny Guy                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
4152df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                if (!info.exported) {
4162df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                    throw new SecurityException("Cannot launch non-exported components "
4172df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                            + component);
4182df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                }
4192df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy
4202df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                // Check that the component actually has Intent.CATEGORY_LAUCNCHER
4212df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                // as calling startActivityAsUser ignores the category and just
4222df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                // resolves based on the component if present.
4232df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent,
424b1b302660cf5b1b1c5b342cc90eca93b8f66890cKenny Guy                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
4252df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                final int size = apps.size();
4262df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                for (int i = 0; i < size; ++i) {
4272df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                    ActivityInfo activityInfo = apps.get(i).activityInfo;
4282df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                    if (activityInfo.packageName.equals(component.getPackageName()) &&
4292df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                            activityInfo.name.equals(component.getClassName())) {
4302df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                        // Found an activity with category launcher that matches
4312df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                        // this component so ok to launch.
4322df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                        launchIntent.setComponent(component);
4332df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                        mContext.startActivityAsUser(launchIntent, opts, user);
4342df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                        return;
4352df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                    }
4362df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                }
4372df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                throw new SecurityException("Attempt to launch activity without "
4382df1892f411de6fa93ba487e3c4d23a079b74fcbKenny Guy                        + " category Intent.CATEGORY_LAUNCHER " + component);
439df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            } finally {
440df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                Binder.restoreCallingIdentity(ident);
441df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
4424f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
4434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
44443204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki        private void prepareIntentForLaunch(@NonNull Intent launchIntent,
44543204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki                @Nullable Rect sourceBounds) {
44643204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            launchIntent.setSourceBounds(sourceBounds);
44743204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki            launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
44843204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki                    | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
44943204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki        }
45043204b8357d781f284037fb8b7b7050ed04a2103Makoto Onuki
451466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy        @Override
452466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy        public void showAppDetailsAsUser(ComponentName component, Rect sourceBounds,
453466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                Bundle opts, UserHandle user) throws RemoteException {
454466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            ensureInUserProfiles(user, "Cannot show app details for unrelated profile " + user);
455466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            if (!isUserEnabled(user)) {
456466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                throw new IllegalStateException("Cannot show app details for disabled profile "
457466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                        + user);
458466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            }
459466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy
460466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            long ident = Binder.clearCallingIdentity();
461466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            try {
462466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                String packageName = component.getPackageName();
463466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
464466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                        Uri.fromParts("package", packageName, null));
465369aad0e23a1ca1417018c540730915760fe2ed3Winson                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
466466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                intent.setSourceBounds(sourceBounds);
467466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                mContext.startActivityAsUser(intent, opts, user);
468466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            } finally {
469466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy                Binder.restoreCallingIdentity(ident);
470466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            }
471466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy        }
472466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy
473466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy
4746f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki        private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
475df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
476df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            /** Checks if user is a profile of or same as listeningUser.
477df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani              * and the user is enabled. */
478df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser,
479df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    String debugMsg) {
480df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                if (user.getIdentifier() == listeningUser.getIdentifier()) {
481df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg);
482df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    return true;
483df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
484df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                long ident = Binder.clearCallingIdentity();
4854f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                try {
486df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    UserInfo userInfo = mUm.getUserInfo(user.getIdentifier());
487df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier());
488df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    if (userInfo == null || listeningUserInfo == null
489df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                            || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID
490df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                            || userInfo.profileGroupId != listeningUserInfo.profileGroupId
491df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                            || !userInfo.isEnabled()) {
492df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        if (DEBUG) {
493df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                            Log.d(TAG, "Not delivering msg from " + user + " to " + listeningUser + ":"
494df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                                    + debugMsg);
495df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        }
496df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        return false;
497df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    } else {
498df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        if (DEBUG) {
499df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                            Log.d(TAG, "Delivering msg from " + user + " to " + listeningUser + ":"
500df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                                    + debugMsg);
501df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        }
502df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        return true;
503df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    }
504df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                } finally {
505df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    Binder.restoreCallingIdentity(ident);
5064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
5074f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
5084f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
5096f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            // TODO Simplify with lambdas.
5106f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
511df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            @Override
512df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            public void onPackageAdded(String packageName, int uid) {
513df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                UserHandle user = new UserHandle(getChangingUserId());
514df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                final int n = mListeners.beginBroadcast();
515df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                for (int i = 0; i < n; i++) {
516df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
517df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
518df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    if (!isEnabledProfileOf(user, listeningUser, "onPackageAdded")) continue;
519df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    try {
520df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        listener.onPackageAdded(user, packageName);
521df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    } catch (RemoteException re) {
522df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        Slog.d(TAG, "Callback failed ", re);
523df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    }
5244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
525df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                mListeners.finishBroadcast();
526df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
527df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                super.onPackageAdded(packageName, uid);
5284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
5294f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
530df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            @Override
531df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            public void onPackageRemoved(String packageName, int uid) {
532df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                UserHandle user = new UserHandle(getChangingUserId());
533df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                final int n = mListeners.beginBroadcast();
534df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                for (int i = 0; i < n; i++) {
535df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
536df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
537df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    if (!isEnabledProfileOf(user, listeningUser, "onPackageRemoved")) continue;
538df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    try {
539df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        listener.onPackageRemoved(user, packageName);
540df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    } catch (RemoteException re) {
541df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        Slog.d(TAG, "Callback failed ", re);
542df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    }
543df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
544df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                mListeners.finishBroadcast();
5454f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
546df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                super.onPackageRemoved(packageName, uid);
547df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
548df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
549df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            @Override
550df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            public void onPackageModified(String packageName) {
551df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                UserHandle user = new UserHandle(getChangingUserId());
552df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                final int n = mListeners.beginBroadcast();
553df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                for (int i = 0; i < n; i++) {
554df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
555df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
556df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    if (!isEnabledProfileOf(user, listeningUser, "onPackageModified")) continue;
557df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    try {
558df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        listener.onPackageChanged(user, packageName);
559df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    } catch (RemoteException re) {
560df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        Slog.d(TAG, "Callback failed ", re);
561df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    }
5624f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
563df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                mListeners.finishBroadcast();
564df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
565df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                super.onPackageModified(packageName);
5664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
5674f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
568df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            @Override
569df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            public void onPackagesAvailable(String[] packages) {
570df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                UserHandle user = new UserHandle(getChangingUserId());
571df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                final int n = mListeners.beginBroadcast();
572df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                for (int i = 0; i < n; i++) {
573df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
574df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
575df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesAvailable")) continue;
576df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    try {
577df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        listener.onPackagesAvailable(user, packages, isReplacing());
578df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    } catch (RemoteException re) {
579df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        Slog.d(TAG, "Callback failed ", re);
580df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    }
581df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                }
582df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                mListeners.finishBroadcast();
5834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
584df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                super.onPackagesAvailable(packages);
585df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
586df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
587df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            @Override
588df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            public void onPackagesUnavailable(String[] packages) {
589df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                UserHandle user = new UserHandle(getChangingUserId());
590df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                final int n = mListeners.beginBroadcast();
591df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                for (int i = 0; i < n; i++) {
592df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
593df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
594df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesUnavailable")) continue;
595df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    try {
596df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        listener.onPackagesUnavailable(user, packages, isReplacing());
597df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    } catch (RemoteException re) {
598df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                        Slog.d(TAG, "Callback failed ", re);
599df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                    }
6004f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
601df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                mListeners.finishBroadcast();
602df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani
603df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                super.onPackagesUnavailable(packages);
6044f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
6054f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
606772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            @Override
607772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            public void onPackagesSuspended(String[] packages) {
608772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                UserHandle user = new UserHandle(getChangingUserId());
609772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                final int n = mListeners.beginBroadcast();
610772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                for (int i = 0; i < n; i++) {
611772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
612772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
613772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesSuspended")) continue;
614772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    try {
615772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                        listener.onPackagesSuspended(user, packages);
616772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    } catch (RemoteException re) {
617772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                        Slog.d(TAG, "Callback failed ", re);
618772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    }
619772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                }
620772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                mListeners.finishBroadcast();
621772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy
622772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                super.onPackagesSuspended(packages);
623772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            }
624772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy
625772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            @Override
626772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            public void onPackagesUnsuspended(String[] packages) {
627772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                UserHandle user = new UserHandle(getChangingUserId());
628772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                final int n = mListeners.beginBroadcast();
629772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                for (int i = 0; i < n; i++) {
630772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
631772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
632772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesUnsuspended")) continue;
633772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    try {
634772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                        listener.onPackagesUnsuspended(user, packages);
635772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    } catch (RemoteException re) {
636772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                        Slog.d(TAG, "Callback failed ", re);
637772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                    }
638772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                }
639772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                mListeners.finishBroadcast();
640772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy
641772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy                super.onPackagesUnsuspended(packages);
642772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy            }
643772427555f2624b38124ab8e586ac0ccc451eb53Kenny Guy
6446f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            @Override
6456f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            public void onShortcutChanged(@NonNull String packageName,
6466f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    @NonNull List<ShortcutInfo> shortcuts, @UserIdInt int userId) {
6476f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                final UserHandle user = UserHandle.of(userId);
6486f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki
6496f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                final int n = mListeners.beginBroadcast();
6506f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                for (int i = 0; i < n; i++) {
6516f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
6526f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
6536f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    if (!isEnabledProfileOf(user, listeningUser, "onShortcutChanged")) continue;
6546f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    try {
6556f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                        listener.onShortcutChanged(user, packageName,
6566f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                                new ParceledListSlice<>(shortcuts));
6576f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    } catch (RemoteException re) {
6586f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                        Slog.d(TAG, "Callback failed ", re);
6596f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                    }
6606f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                }
6616f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki                mListeners.finishBroadcast();
6626f7362d92573e4ae693bc513dca586d6a4eb087bMakoto Onuki            }
6634f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
6644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
665df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani        class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> {
666df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            @Override
667df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            public void onCallbackDied(T callback, Object cookie) {
668df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani                checkCallbackCount();
669df7db074b5e6a19c8a33c2cc6be88f85eb5ee47cAmith Yamasani            }
6704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
6714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
672b6830197450d5a2befaf0dc4f7e73850f4c55846Nicolas Prevot}
673