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;
28b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guyimport android.os.Handler;
29b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guyimport android.os.Looper;
30b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guyimport android.os.Message;
314f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.RemoteException;
324f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.os.UserHandle;
33e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasaniimport android.os.UserManager;
344f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport android.util.Log;
354f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
364f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.ArrayList;
374f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.Collections;
384f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasaniimport java.util.List;
394f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani/**
414f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Class for retrieving a list of launchable activities for the current user and any associated
424f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * managed profiles. This is mainly for use by launchers. Apps can be queried for each user profile.
434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * Since the PackageManager will not deliver package broadcasts for other profiles, you can register
444f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani * for package changes here.
45e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * <p>
46e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * To watch for managed profiles being added or removed, register for the following broadcasts:
47e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * {@link Intent#ACTION_MANAGED_PROFILE_ADDED} and {@link Intent#ACTION_MANAGED_PROFILE_REMOVED}.
48e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * <p>
49e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * You can retrieve the list of profiles associated with this user with
50e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani * {@link UserManager#getUserProfiles()}.
514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani */
524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasanipublic class LauncherApps {
534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    static final String TAG = "LauncherApps";
554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    static final boolean DEBUG = false;
564f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    private Context mContext;
584f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    private ILauncherApps mService;
59e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani    private PackageManager mPm;
604f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
61b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy    private List<CallbackMessageHandler> mCallbacks
62b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            = new ArrayList<CallbackMessageHandler>();
63c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy
64c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy    /**
65c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy     * Callbacks for package changes to this and related managed profiles.
66c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy     */
67f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy    public static abstract class Callback {
68c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        /**
69c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * Indicates that a package was removed from the specified profile.
70c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *
71b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy         * If a package is removed while being updated onPackageChanged will be
72b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy         * called instead.
73b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy         *
74c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param packageName The name of the package that was removed.
75c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param user The UserHandle of the profile that generated the change.
76c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         */
77c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        abstract public void onPackageRemoved(String packageName, UserHandle user);
78c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy
79c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        /**
80c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * Indicates that a package was added to the specified profile.
81c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *
82b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy         * If a package is added while being updated then onPackageChanged will be
83b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy         * called instead.
84b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy         *
85c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param packageName The name of the package that was added.
86c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param user The UserHandle of the profile that generated the change.
87c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         */
88c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        abstract public void onPackageAdded(String packageName, UserHandle user);
89c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy
90c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        /**
91c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * Indicates that a package was modified in the specified profile.
92b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy         * This can happen, for example, when the package is updated or when
93b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy         * one or more components are enabled or disabled.
94c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *
95c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param packageName The name of the package that has changed.
96c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param user The UserHandle of the profile that generated the change.
97c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         */
98c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        abstract public void onPackageChanged(String packageName, UserHandle user);
99c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy
100c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        /**
101c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * Indicates that one or more packages have become available. For
102c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * example, this can happen when a removable storage card has
103c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * reappeared.
104c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *
105c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param packageNames The names of the packages that have become
106c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *            available.
107c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param user The UserHandle of the profile that generated the change.
108c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param replacing Indicates whether these packages are replacing
109c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *            existing ones.
110c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         */
111c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        abstract public void onPackagesAvailable(String[] packageNames, UserHandle user,
112c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                boolean replacing);
113c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy
114c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        /**
115c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * Indicates that one or more packages have become unavailable. For
116c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * example, this can happen when a removable storage card has been
117c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * removed.
118c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *
119c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param packageNames The names of the packages that have become
120c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *            unavailable.
121c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param user The UserHandle of the profile that generated the change.
122c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         * @param replacing Indicates whether the packages are about to be
123c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         *            replaced with new versions.
124c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy         */
125c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        abstract public void onPackagesUnavailable(String[] packageNames, UserHandle user,
126c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                boolean replacing);
127c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy    }
1284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
1294f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /** @hide */
1304f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public LauncherApps(Context context, ILauncherApps service) {
1314f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        mContext = context;
1324f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        mService = service;
133e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani        mPm = context.getPackageManager();
1344f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
1354f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
1364f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
1374f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * Retrieves a list of launchable activities that match {@link Intent#ACTION_MAIN} and
1384f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * {@link Intent#CATEGORY_LAUNCHER}, for a specified user.
1394f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *
1404f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param packageName The specific package to query. If null, it checks all installed packages
1414f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *            in the profile.
1424f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param user The UserHandle of the profile.
1434f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @return List of launchable activities. Can be an empty list but will not be null.
1444f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     */
1454f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
1464f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        List<ResolveInfo> activities = null;
1474f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        try {
1484f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            activities = mService.getLauncherActivities(packageName, user);
1494f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        } catch (RemoteException re) {
1504f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        if (activities == null) {
1524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            return Collections.EMPTY_LIST;
1534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1544f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        ArrayList<LauncherActivityInfo> lais = new ArrayList<LauncherActivityInfo>();
1554f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        final int count = activities.size();
1564f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        for (int i = 0; i < count; i++) {
1574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            ResolveInfo ri = activities.get(i);
158e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            long firstInstallTime = 0;
159e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            try {
160e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                firstInstallTime = mPm.getPackageInfo(ri.activityInfo.packageName,
161e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    PackageManager.GET_UNINSTALLED_PACKAGES).firstInstallTime;
162e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            } catch (NameNotFoundException nnfe) {
163e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                // Sorry, can't find package
164e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            }
165e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            LauncherActivityInfo lai = new LauncherActivityInfo(mContext, ri, user,
166e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    firstInstallTime);
1674f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
1684f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.v(TAG, "Returning activity for profile " + user + " : "
1694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                        + lai.getComponentName());
1704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
1714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            lais.add(lai);
1724f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
1734f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        return lais;
1744f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
1754f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
1764f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    static ComponentName getComponentName(ResolveInfo ri) {
1774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        return new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
1784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
1794f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
1804f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
1814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * Returns the activity info for a given intent and user handle, if it resolves. Otherwise it
1824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * returns null.
1834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *
1844f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param intent The intent to find a match for.
1854f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param user The profile to look in for a match.
1864f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @return An activity info object if there is a match.
1874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     */
1884f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
1894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        try {
1904f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            ResolveInfo ri = mService.resolveActivity(intent, user);
1914f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (ri != null) {
192e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                long firstInstallTime = 0;
193e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                try {
194e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    firstInstallTime = mPm.getPackageInfo(ri.activityInfo.packageName,
195e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                            PackageManager.GET_UNINSTALLED_PACKAGES).firstInstallTime;
196e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                } catch (NameNotFoundException nnfe) {
197e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    // Sorry, can't find package
198e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                }
199e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                LauncherActivityInfo info = new LauncherActivityInfo(mContext, ri, user,
200e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                        firstInstallTime);
2014f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                return info;
2024f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
2034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        } catch (RemoteException re) {
204ad97b8b905bb6f0a30241bea27a56572068c39abAmith Yamasani            throw new RuntimeException("Failed to call LauncherAppsService");
2054f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
2064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        return null;
2074f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
2084f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
2094f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
210f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy     * Starts a Main activity in the specified profile.
2114f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     *
2124f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani     * @param component The ComponentName of the activity to launch
213e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * @param user The UserHandle of the profile
214e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * @param sourceBounds The Rect containing the source bounds of the clicked icon
215e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     * @param opts Options to pass to startActivity
216e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani     */
217f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy    public void startMainActivity(ComponentName component, UserHandle user, Rect sourceBounds,
218e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani            Bundle opts) {
2195abdbb656063160ff8df2306bd01feba0714d4c1Amith Yamasani        if (DEBUG) {
220f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy            Log.i(TAG, "StartMainActivity " + component + " " + user.getIdentifier());
2215abdbb656063160ff8df2306bd01feba0714d4c1Amith Yamasani        }
2224f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        try {
2234f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            mService.startActivityAsUser(component, sourceBounds, opts, user);
2244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        } catch (RemoteException re) {
2254f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            // Oops!
2264f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
2274f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
2284f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
2294f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    /**
230466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy     * Starts the settings activity to show the application details for a
231466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy     * package in the specified profile.
232466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy     *
233466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy     * @param component The ComponentName of the package to launch settings for.
234466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy     * @param user The UserHandle of the profile
235466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy     * @param sourceBounds The Rect containing the source bounds of the clicked icon
236466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy     * @param opts Options to pass to startActivity
237466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy     */
238f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy    public void startAppDetailsActivity(ComponentName component, UserHandle user,
239466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            Rect sourceBounds, Bundle opts) {
240466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy        try {
241466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            mService.showAppDetailsAsUser(component, sourceBounds, opts, user);
242466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy        } catch (RemoteException re) {
243466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy            // Oops!
244466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy        }
245466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy    }
246466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy
247466d203c4ff032477d9a6bdb077ce3cd9b4fe070Kenny Guy    /**
24853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * Checks if the package is installed and enabled for a profile.
24953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     *
25053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @param packageName The package to check.
25153fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @param user The UserHandle of the profile.
25253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     *
25353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @return true if the package exists and is enabled.
25453fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     */
255f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy    public boolean isPackageEnabled(String packageName, UserHandle user) {
25653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        try {
25753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy            return mService.isPackageEnabled(packageName, user);
25853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        } catch (RemoteException re) {
259ad97b8b905bb6f0a30241bea27a56572068c39abAmith Yamasani            throw new RuntimeException("Failed to call LauncherAppsService");
26053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        }
26153fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    }
26253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy
26353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    /**
26453fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * Checks if the activity exists and it enabled for a profile.
26553fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     *
26653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @param component The activity to check.
26753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @param user The UserHandle of the profile.
26853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     *
26953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     * @return true if the activity exists and is enabled.
27053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy     */
271f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy    public boolean isActivityEnabled(ComponentName component, UserHandle user) {
27253fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        try {
27353fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy            return mService.isActivityEnabled(component, user);
27453fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        } catch (RemoteException re) {
275ad97b8b905bb6f0a30241bea27a56572068c39abAmith Yamasani            throw new RuntimeException("Failed to call LauncherAppsService");
27653fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy        }
27753fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    }
27853fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy
27953fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy
28053fa4ec7f466e70fe3e33d15c4abfc9bb557eb10Kenny Guy    /**
28110a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy     * Registers a callback for changes to packages in current and managed profiles.
282c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy     *
28310a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy     * @param callback The callback to register.
284c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy     */
28510a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy    public void registerCallback(Callback callback) {
28610a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy        registerCallback(callback, null);
287b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy    }
288b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
289b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy    /**
29010a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy     * Registers a callback for changes to packages in current and managed profiles.
291b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy     *
29210a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy     * @param callback The callback to register.
293b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy     * @param handler that should be used to post callbacks on, may be null.
294b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy     */
29510a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy    public void registerCallback(Callback callback, Handler handler) {
296c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        synchronized (this) {
297c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy            if (callback != null && !mCallbacks.contains(callback)) {
298b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                boolean addedFirstCallback = mCallbacks.size() == 0;
299b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                addCallbackLocked(callback, handler);
300b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                if (addedFirstCallback) {
301c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                    try {
302c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                        mService.addOnAppsChangedListener(mAppsChangedListener);
303c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                    } catch (RemoteException re) {
304c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                    }
305c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                }
306c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy            }
307c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        }
308c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy    }
309c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy
310c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy    /**
31110a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy     * Unregisters a callback that was previously registered.
312c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy     *
31310a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy     * @param callback The callback to unregister.
31410a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy     * @see #registerCallback(Callback)
315c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy     */
31610a574fbf3c786791b84078f41932f83ad3e34ffKenny Guy    public void unregisterCallback(Callback callback) {
317c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy        synchronized (this) {
318b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            removeCallbackLocked(callback);
31944b6dee70eb2dfb7e26aeec9b2640d64e4f7d199Kenny Guy            if (mCallbacks.size() == 0) {
320e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                try {
321e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                    mService.removeOnAppsChangedListener(mAppsChangedListener);
322e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                } catch (RemoteException re) {
323e781c81d3394642583d555e7a5d6f6f8f63bc538Amith Yamasani                }
3244f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3254f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3264f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    }
3274f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
328f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy    private void removeCallbackLocked(Callback callback) {
329b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        if (callback == null) {
330b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            throw new IllegalArgumentException("Callback cannot be null");
331b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
332b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        final int size = mCallbacks.size();
333b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        for (int i = 0; i < size; ++i) {
334b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            if (mCallbacks.get(i).mCallback == callback) {
335b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                mCallbacks.remove(i);
336b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                return;
337b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            }
338b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
339b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy    }
340b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
341f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy    private void addCallbackLocked(Callback callback, Handler handler) {
342b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        // Remove if already present.
343b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        removeCallbackLocked(callback);
344b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        if (handler == null) {
345b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            handler = new Handler();
346b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
347b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        CallbackMessageHandler toAdd = new CallbackMessageHandler(handler.getLooper(), callback);
348b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        mCallbacks.add(toAdd);
349b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy    }
350b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
3514f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    private IOnAppsChangedListener.Stub mAppsChangedListener = new IOnAppsChangedListener.Stub() {
3524f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3534f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
354b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        public void onPackageRemoved(UserHandle user, String packageName)
355b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                throws RemoteException {
3564f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
3574f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackageRemoved " + user.getIdentifier() + "," + packageName);
3584f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3594f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
360b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                for (CallbackMessageHandler callback : mCallbacks) {
361b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    callback.postOnPackageRemoved(packageName, user);
362c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                }
3634f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3644f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3654f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3664f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
3674f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackageChanged(UserHandle user, String packageName) throws RemoteException {
3684f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
3694f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackageChanged " + user.getIdentifier() + "," + packageName);
3704f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3714f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
372b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                for (CallbackMessageHandler callback : mCallbacks) {
373b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    callback.postOnPackageChanged(packageName, user);
374c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                }
3754f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3764f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3774f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3784f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
3794f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackageAdded(UserHandle user, String packageName) throws RemoteException {
3804f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
3814f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackageAdded " + user.getIdentifier() + "," + packageName);
3824f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3834f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
384b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                for (CallbackMessageHandler callback : mCallbacks) {
385b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    callback.postOnPackageAdded(packageName, user);
386c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                }
3874f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3884f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
3894f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
3904f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
3914f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing)
3924f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                throws RemoteException {
3934f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
3944f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackagesAvailable " + user.getIdentifier() + "," + packageNames);
3954f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
3964f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
397b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                for (CallbackMessageHandler callback : mCallbacks) {
398b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    callback.postOnPackagesAvailable(packageNames, user, replacing);
399c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                }
4004f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
4014f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
4024f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani
4034f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        @Override
4044f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        public void onPackagesUnavailable(UserHandle user, String[] packageNames, boolean replacing)
4054f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                throws RemoteException {
4064f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            if (DEBUG) {
4074f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani                Log.d(TAG, "onPackagesUnavailable " + user.getIdentifier() + "," + packageNames);
4084f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            }
4094f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani            synchronized (LauncherApps.this) {
410b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                for (CallbackMessageHandler callback : mCallbacks) {
411b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    callback.postOnPackagesUnavailable(packageNames, user, replacing);
412c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy                }
413c0154537b0b7926ce6a3c778597b3c2735ca5497Kenny Guy           }
4144f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani        }
4154f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani    };
416b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
417b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy    private static class CallbackMessageHandler extends Handler {
418b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        private static final int MSG_ADDED = 1;
419b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        private static final int MSG_REMOVED = 2;
420b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        private static final int MSG_CHANGED = 3;
421b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        private static final int MSG_AVAILABLE = 4;
422b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        private static final int MSG_UNAVAILABLE = 5;
423b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
424f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy        private LauncherApps.Callback mCallback;
425b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
426b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        private static class CallbackInfo {
427b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            String[] packageNames;
428b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            String packageName;
429b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            boolean replacing;
430b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            UserHandle user;
431b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
432b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
433f939dbaf766bd81b10bfc44fd493647180eabad8Kenny Guy        public CallbackMessageHandler(Looper looper, LauncherApps.Callback callback) {
434b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            super(looper, null, true);
435b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            mCallback = callback;
436b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
437b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
438b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        @Override
439b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        public void handleMessage(Message msg) {
440b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            if (mCallback == null || !(msg.obj instanceof CallbackInfo)) {
441b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                return;
442b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            }
443b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            CallbackInfo info = (CallbackInfo) msg.obj;
444b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            switch (msg.what) {
445b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                case MSG_ADDED:
446b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    mCallback.onPackageAdded(info.packageName, info.user);
447b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    break;
448b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                case MSG_REMOVED:
449b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    mCallback.onPackageRemoved(info.packageName, info.user);
450b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    break;
451b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                case MSG_CHANGED:
452b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    mCallback.onPackageChanged(info.packageName, info.user);
453b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    break;
454b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                case MSG_AVAILABLE:
455b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    mCallback.onPackagesAvailable(info.packageNames, info.user, info.replacing);
456b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    break;
457b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                case MSG_UNAVAILABLE:
458b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    mCallback.onPackagesUnavailable(info.packageNames, info.user, info.replacing);
459b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                    break;
460b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            }
461b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
462b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
463b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        public void postOnPackageAdded(String packageName, UserHandle user) {
464b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            CallbackInfo info = new CallbackInfo();
465b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.packageName = packageName;
466b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.user = user;
467b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            obtainMessage(MSG_ADDED, info).sendToTarget();
468b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
469b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
470b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        public void postOnPackageRemoved(String packageName, UserHandle user) {
471b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            CallbackInfo info = new CallbackInfo();
472b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.packageName = packageName;
473b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.user = user;
474b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            obtainMessage(MSG_REMOVED, info).sendToTarget();
475b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
476b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
477b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        public void postOnPackageChanged(String packageName, UserHandle user) {
478b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            CallbackInfo info = new CallbackInfo();
479b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.packageName = packageName;
480b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.user = user;
481b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            obtainMessage(MSG_CHANGED, info).sendToTarget();
482b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
483b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
484b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        public void postOnPackagesAvailable(String[] packageNames, UserHandle user,
485b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                boolean replacing) {
486b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            CallbackInfo info = new CallbackInfo();
487b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.packageNames = packageNames;
488b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.replacing = replacing;
489b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.user = user;
490b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            obtainMessage(MSG_AVAILABLE, info).sendToTarget();
491b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
492b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy
493b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        public void postOnPackagesUnavailable(String[] packageNames, UserHandle user,
494b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy                boolean replacing) {
495b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            CallbackInfo info = new CallbackInfo();
496b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.packageNames = packageNames;
497b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.replacing = replacing;
498b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            info.user = user;
499b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy            obtainMessage(MSG_UNAVAILABLE, info).sendToTarget();
500b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy        }
501b42c89bfb0415d2a4b1d8b7247309f15fd348974Kenny Guy    }
5024f58263d02f296430a9653126d28501e95c7bb6cAmith Yamasani}
503