LauncherApps.java revision e781c81d3394642583d555e7a5d6f6f8f63bc538
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 android.content.pm;
184f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
19e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasaniimport android.app.AppGlobals;
204f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.ComponentName;
214f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.Context;
224f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.Intent;
234f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.ILauncherApps;
244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.content.pm.IOnAppsChangedListener;
25e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasaniimport android.content.pm.PackageManager.NameNotFoundException;
264f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.graphics.Rect;
274f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.Bundle;
284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteException;
294f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserHandle;
30e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasaniimport android.os.UserManager;
314f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.util.Log;
324f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
334f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.ArrayList;
344f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.Collections;
354f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.List;
364f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
374f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/**
384f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Class for retrieving a list of launchable activities for the current user and any associated
394f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * managed profiles. This is mainly for use by launchers. Apps can be queried for each user profile.
404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Since the PackageManager will not deliver package broadcasts for other profiles, you can register
414f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * for package changes here.
42e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * <p>
43e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * To watch for managed profiles being added or removed, register for the following broadcasts:
44e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * {@link Intent#ACTION_MANAGED_PROFILE_ADDED} and {@link Intent#ACTION_MANAGED_PROFILE_REMOVED}.
45e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * <p>
46e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * You can retrieve the list of profiles associated with this user with
47e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * {@link UserManager#getUserProfiles()}.
484f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */
494f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasanipublic class LauncherApps {
504f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    static final String TAG = "LauncherApps";
524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    static final boolean DEBUG = false;
534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    private Context mContext;
554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    private ILauncherApps mService;
56e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani    private PackageManager mPm;
574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
584f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    private List<OnAppsChangedListener> mListeners
594f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            = new ArrayList<OnAppsChangedListener>();
604f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
614f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
62e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * Callbacks for package changes to this and related managed profiles.
634f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     */
644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public interface OnAppsChangedListener {
654f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        /**
664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * Indicates that a package was removed from the specified profile.
674f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *
684f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param user The UserHandle of the profile that generated the change.
694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param packageName The name of the package that was removed.
70e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @hide remove before ship
714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         */
724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        void onPackageRemoved(UserHandle user, String packageName);
734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        /**
754f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * Indicates that a package was added to the specified profile.
764f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *
774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param user The UserHandle of the profile that generated the change.
784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param packageName The name of the package that was added.
79e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @hide remove before ship
804f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         */
814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        void onPackageAdded(UserHandle user, String packageName);
824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        /**
844f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * Indicates that a package was modified in the specified profile.
854f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *
864f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param user The UserHandle of the profile that generated the change.
874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param packageName The name of the package that has changed.
88e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @hide remove before ship
894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         */
904f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        void onPackageChanged(UserHandle user, String packageName);
914f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
924f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        /**
934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * Indicates that one or more packages have become available. For
944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * example, this can happen when a removable storage card has
954f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * reappeared.
964f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *
974f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param user The UserHandle of the profile that generated the change.
984f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param packageNames The names of the packages that have become
994f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *            available.
1004f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param replacing Indicates whether these packages are replacing
1014f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *            existing ones.
102e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @hide remove before ship
1034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         */
1044f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing);
1054f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
1064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        /**
1074f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * Indicates that one or more packages have become unavailable. For
1084f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * example, this can happen when a removable storage card has been
1094f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * removed.
1104f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *
1114f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param user The UserHandle of the profile that generated the change.
1124f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param packageNames The names of the packages that have become
1134f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *            unavailable.
1144f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         * @param replacing Indicates whether the packages are about to be
1154f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         *            replaced with new versions.
116e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @hide remove before ship
1174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani         */
1184f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        void onPackagesUnavailable(UserHandle user, String[] packageNames, boolean replacing);
119e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani
120e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        /**
121e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * Indicates that a package was removed from the specified profile.
122e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *
123e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param packageName The name of the package that was removed.
124e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param user The UserHandle of the profile that generated the change.
125e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         */
126e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        void onPackageRemoved(String packageName, UserHandle user);
127e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani
128e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        /**
129e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * Indicates that a package was added to the specified profile.
130e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *
131e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param packageName The name of the package that was added.
132e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param user The UserHandle of the profile that generated the change.
133e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         */
134e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        void onPackageAdded(String packageName, UserHandle user);
135e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani
136e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        /**
137e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * Indicates that a package was modified in the specified profile.
138e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *
139e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param packageName The name of the package that has changed.
140e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param user The UserHandle of the profile that generated the change.
141e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         */
142e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        void onPackageChanged(String packageName, UserHandle user);
143e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani
144e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        /**
145e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * Indicates that one or more packages have become available. For
146e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * example, this can happen when a removable storage card has
147e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * reappeared.
148e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *
149e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param packageNames The names of the packages that have become
150e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *            available.
151e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param user The UserHandle of the profile that generated the change.
152e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param replacing Indicates whether these packages are replacing
153e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *            existing ones.
154e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         */
155e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        void onPackagesAvailable(String [] packageNames, UserHandle user, boolean replacing);
156e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani
157e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        /**
158e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * Indicates that one or more packages have become unavailable. For
159e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * example, this can happen when a removable storage card has been
160e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * removed.
161e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *
162e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param packageNames The names of the packages that have become
163e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *            unavailable.
164e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param user The UserHandle of the profile that generated the change.
165e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         * @param replacing Indicates whether the packages are about to be
166e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         *            replaced with new versions.
167e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani         */
168e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing);
1694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
1704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
1714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /** @hide */
1724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public LauncherApps(Context context, ILauncherApps service) {
1734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        mContext = context;
1744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        mService = service;
175e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        mPm = context.getPackageManager();
1764f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
1774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
1784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
1794f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * Retrieves a list of launchable activities that match {@link Intent#ACTION_MAIN} and
1804f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * {@link Intent#CATEGORY_LAUNCHER}, for a specified user.
1814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *
1824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param packageName The specific package to query. If null, it checks all installed packages
1834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *            in the profile.
1844f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param user The UserHandle of the profile.
1854f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @return List of launchable activities. Can be an empty list but will not be null.
1864f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     */
1874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
1884f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        List<ResolveInfo> activities = null;
1894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        try {
1904f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            activities = mService.getLauncherActivities(packageName, user);
1914f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        } catch (RemoteException re) {
1924f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        if (activities == null) {
1944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            return Collections.EMPTY_LIST;
1954f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1964f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        ArrayList<LauncherActivityInfo> lais = new ArrayList<LauncherActivityInfo>();
1974f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        final int count = activities.size();
1984f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        for (int i = 0; i < count; i++) {
1994f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            ResolveInfo ri = activities.get(i);
200e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            long firstInstallTime = 0;
201e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            try {
202e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                firstInstallTime = mPm.getPackageInfo(ri.activityInfo.packageName,
203e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    PackageManager.GET_UNINSTALLED_PACKAGES).firstInstallTime;
204e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            } catch (NameNotFoundException nnfe) {
205e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                // Sorry, can't find package
206e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            }
207e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            LauncherActivityInfo lai = new LauncherActivityInfo(mContext, ri, user,
208e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    firstInstallTime);
2094f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
2104f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.v(TAG, "Returning activity for profile " + user + " : "
2114f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                        + lai.getComponentName());
2124f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
2134f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            lais.add(lai);
2144f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
2154f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        return lais;
2164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
2174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
2184f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    static ComponentName getComponentName(ResolveInfo ri) {
2194f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        return new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
2204f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
2214f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
2224f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
2234f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * Returns the activity info for a given intent and user handle, if it resolves. Otherwise it
2244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * returns null.
2254f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *
2264f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param intent The intent to find a match for.
2274f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param user The profile to look in for a match.
2284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @return An activity info object if there is a match.
2294f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     */
2304f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
2314f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        try {
2324f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            ResolveInfo ri = mService.resolveActivity(intent, user);
2334f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (ri != null) {
234e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                long firstInstallTime = 0;
235e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                try {
236e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    firstInstallTime = mPm.getPackageInfo(ri.activityInfo.packageName,
237e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                            PackageManager.GET_UNINSTALLED_PACKAGES).firstInstallTime;
238e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                } catch (NameNotFoundException nnfe) {
239e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    // Sorry, can't find package
240e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                }
241e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                LauncherActivityInfo info = new LauncherActivityInfo(mContext, ri, user,
242e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                        firstInstallTime);
2434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                return info;
2444f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
2454f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        } catch (RemoteException re) {
2464f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            return null;
2474f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
2484f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        return null;
2494f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
2504f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
2514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
2524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * Starts an activity in the specified profile.
2534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *
2544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param component The ComponentName of the activity to launch
2554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param sourceBounds The Rect containing the source bounds of the clicked icon
2564f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param opts Options to pass to startActivity
2574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param user The UserHandle of the profile
258e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * @hide remove before ship
2594f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     */
2604f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public void startActivityForProfile(ComponentName component, Rect sourceBounds,
2614f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            Bundle opts, UserHandle user) {
262e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        startActivityForProfile(component, user, sourceBounds, opts);
263e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani    }
264e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani
265e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani    /**
266e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * Starts an activity in the specified profile.
267e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     *
268e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * @param component The ComponentName of the activity to launch
269e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * @param user The UserHandle of the profile
270e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * @param sourceBounds The Rect containing the source bounds of the clicked icon
271e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * @param opts Options to pass to startActivity
272e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     */
273e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani    public void startActivityForProfile(ComponentName component, UserHandle user, Rect sourceBounds,
274e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            Bundle opts) {
2755abdbb656063160ff8df2306bd01feba0714d4c1Amith Yamasani        if (DEBUG) {
2765abdbb656063160ff8df2306bd01feba0714d4c1Amith Yamasani            Log.i(TAG, "StartActivityForProfile " + component + " " + user.getIdentifier());
2775abdbb656063160ff8df2306bd01feba0714d4c1Amith Yamasani        }
2784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        try {
2794f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            mService.startActivityAsUser(component, sourceBounds, opts, user);
2804f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        } catch (RemoteException re) {
2814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            // Oops!
2824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
2834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
2844f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
2854f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
28653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * Checks if the package is installed and enabled for a profile.
28753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     *
28853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @param packageName The package to check.
28953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @param user The UserHandle of the profile.
29053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     *
29153fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @return true if the package exists and is enabled.
29253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     */
29353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    public boolean isPackageEnabledForProfile(String packageName, UserHandle user) {
29453fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        try {
29553fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy            return mService.isPackageEnabled(packageName, user);
29653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        } catch (RemoteException re) {
29753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy            return false;
29853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        }
29953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    }
30053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy
30153fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    /**
30253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * Checks if the activity exists and it enabled for a profile.
30353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     *
30453fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @param component The activity to check.
30553fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @param user The UserHandle of the profile.
30653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     *
30753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @return true if the activity exists and is enabled.
30853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     */
30953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) {
31053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        try {
31153fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy            return mService.isActivityEnabled(component, user);
31253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        } catch (RemoteException re) {
31353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy            return false;
31453fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        }
31553fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    }
31653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy
31753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy
31853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    /**
3194f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * Adds a listener for changes to packages in current and managed profiles.
3204f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *
3214f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param listener The listener to add.
3224f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     */
323e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani    public void addOnAppsChangedListener(OnAppsChangedListener listener) {
324e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        synchronized (this) {
325e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            if (listener != null && !mListeners.contains(listener)) {
326e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                mListeners.add(listener);
327e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                if (mListeners.size() == 1) {
328e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    try {
329e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                        mService.addOnAppsChangedListener(mAppsChangedListener);
330e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    } catch (RemoteException re) {
331e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    }
3324f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
3334f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3344f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3354f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
3364f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3374f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
3384f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * Removes a listener that was previously added.
3394f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *
3404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param listener The listener to remove.
3414f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @see #addOnAppsChangedListener(OnAppsChangedListener)
3424f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     */
343e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani    public void removeOnAppsChangedListener(OnAppsChangedListener listener) {
344e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        synchronized (this) {
345e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            mListeners.remove(listener);
346e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            if (mListeners.size() == 0) {
347e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                try {
348e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    mService.removeOnAppsChangedListener(mAppsChangedListener);
349e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                } catch (RemoteException re) {
350e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                }
3514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
3544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    private IOnAppsChangedListener.Stub mAppsChangedListener = new IOnAppsChangedListener.Stub() {
3564f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
3584f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackageRemoved(UserHandle user, String packageName) throws RemoteException {
3594f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
3604f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackageRemoved " + user.getIdentifier() + "," + packageName);
3614f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3624f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
3634f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                for (OnAppsChangedListener listener : mListeners) {
364e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackageRemoved(user, packageName); // TODO: Remove before ship
365e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackageRemoved(packageName, user);
3664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
3674f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3684f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
3714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackageChanged(UserHandle user, String packageName) throws RemoteException {
3724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
3734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackageChanged " + user.getIdentifier() + "," + packageName);
3744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3754f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
3764f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                for (OnAppsChangedListener listener : mListeners) {
377e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackageChanged(user, packageName); // TODO: Remove before ship
378e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackageChanged(packageName, user);
3794f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
3804f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
3844f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackageAdded(UserHandle user, String packageName) throws RemoteException {
3854f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
3864f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackageAdded " + user.getIdentifier() + "," + packageName);
3874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3884f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
3894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                for (OnAppsChangedListener listener : mListeners) {
390e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackageAdded(user, packageName); // TODO: Remove before ship
391e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackageAdded(packageName, user);
3924f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
3934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3954f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3964f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
3974f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing)
3984f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                throws RemoteException {
3994f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
4004f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackagesAvailable " + user.getIdentifier() + "," + packageNames);
4014f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
4024f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
4034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                for (OnAppsChangedListener listener : mListeners) {
404e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackagesAvailable(user, packageNames, replacing); // TODO: Remove
405e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackagesAvailable(packageNames, user, replacing);
4064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
4074f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
4084f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
4094f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
4104f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
4114f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackagesUnavailable(UserHandle user, String[] packageNames, boolean replacing)
4124f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                throws RemoteException {
4134f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
4144f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackagesUnavailable " + user.getIdentifier() + "," + packageNames);
4154f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
4164f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
4174f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                for (OnAppsChangedListener listener : mListeners) {
418e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackagesUnavailable(user, packageNames, replacing); // TODO: Remove
419e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    listener.onPackagesUnavailable(packageNames, user, replacing);
4204f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                }
4214f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
4224f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
4234f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    };
4244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani}
425