LauncherAppsCompatVL.java revision e3c59256794448c67e01333a9f5036559b1bd502
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.launcher3.compat;
18
19import android.content.ComponentName;
20import android.content.Context;
21import android.content.Intent;
22import android.content.pm.ApplicationInfo;
23import android.content.pm.LauncherActivityInfo;
24import android.content.pm.LauncherApps;
25import android.content.pm.PackageManager;
26import android.content.pm.ResolveInfo;
27import android.content.pm.ShortcutInfo;
28import android.graphics.Rect;
29import android.os.Bundle;
30import android.os.Process;
31import android.os.UserHandle;
32import android.support.annotation.Nullable;
33
34import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVL;
35import com.android.launcher3.shortcuts.ShortcutInfoCompat;
36import com.android.launcher3.util.PackageUserKey;
37
38import java.util.ArrayList;
39import java.util.HashMap;
40import java.util.List;
41import java.util.Map;
42
43public class LauncherAppsCompatVL extends LauncherAppsCompat {
44
45    protected final LauncherApps mLauncherApps;
46    protected final Context mContext;
47
48    private Map<OnAppsChangedCallbackCompat, WrappedCallback> mCallbacks = new HashMap<>();
49
50    LauncherAppsCompatVL(Context context) {
51        mContext = context;
52        mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
53    }
54
55    @Override
56    public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
57        return mLauncherApps.getActivityList(packageName, user);
58    }
59
60    @Override
61    public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
62        return mLauncherApps.resolveActivity(intent, user);
63    }
64
65    @Override
66    public void startActivityForProfile(ComponentName component, UserHandle user,
67            Rect sourceBounds, Bundle opts) {
68        mLauncherApps.startMainActivity(component, user, sourceBounds, opts);
69    }
70
71    @Override
72    public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) {
73        final boolean isPrimaryUser = Process.myUserHandle().equals(user);
74        if (!isPrimaryUser && (flags == 0)) {
75            // We are looking for an installed app on a secondary profile. Prior to O, the only
76            // entry point for work profiles is through the LauncherActivity.
77            List<LauncherActivityInfo> activityList =
78                    mLauncherApps.getActivityList(packageName, user);
79            return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null;
80        }
81        try {
82            ApplicationInfo info =
83                    mContext.getPackageManager().getApplicationInfo(packageName, flags);
84            // There is no way to check if the app is installed for managed profile. But for
85            // primary profile, we can still have this check.
86            if (isPrimaryUser && ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0)
87                    || !info.enabled) {
88                return null;
89            }
90            return info;
91        } catch (PackageManager.NameNotFoundException e) {
92            // Package not found
93            return null;
94        }
95    }
96
97    @Override
98    public void showAppDetailsForProfile(ComponentName component, UserHandle user,
99            Rect sourceBounds, Bundle opts) {
100        mLauncherApps.startAppDetailsActivity(component, user, sourceBounds, opts);
101    }
102
103    @Override
104    public void addOnAppsChangedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
105        WrappedCallback wrappedCallback = new WrappedCallback(callback);
106        synchronized (mCallbacks) {
107            mCallbacks.put(callback, wrappedCallback);
108        }
109        mLauncherApps.registerCallback(wrappedCallback);
110    }
111
112    @Override
113    public void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) {
114        final WrappedCallback wrappedCallback;
115        synchronized (mCallbacks) {
116            wrappedCallback = mCallbacks.remove(callback);
117        }
118        if (wrappedCallback != null) {
119            mLauncherApps.unregisterCallback(wrappedCallback);
120        }
121    }
122
123    @Override
124    public boolean isPackageEnabledForProfile(String packageName, UserHandle user) {
125        return mLauncherApps.isPackageEnabled(packageName, user);
126    }
127
128    @Override
129    public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) {
130        return mLauncherApps.isActivityEnabled(component, user);
131    }
132
133    private static class WrappedCallback extends LauncherApps.Callback {
134        private LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;
135
136        public WrappedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
137            mCallback = callback;
138        }
139
140        public void onPackageRemoved(String packageName, UserHandle user) {
141            mCallback.onPackageRemoved(packageName, user);
142        }
143
144        public void onPackageAdded(String packageName, UserHandle user) {
145            mCallback.onPackageAdded(packageName, user);
146        }
147
148        public void onPackageChanged(String packageName, UserHandle user) {
149            mCallback.onPackageChanged(packageName, user);
150        }
151
152        public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
153            mCallback.onPackagesAvailable(packageNames, user, replacing);
154        }
155
156        public void onPackagesUnavailable(String[] packageNames, UserHandle user,
157                boolean replacing) {
158            mCallback.onPackagesUnavailable(packageNames, user, replacing);
159        }
160
161        public void onPackagesSuspended(String[] packageNames, UserHandle user) {
162            mCallback.onPackagesSuspended(packageNames, user);
163        }
164
165        public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
166            mCallback.onPackagesUnsuspended(packageNames, user);
167        }
168
169        public void onShortcutsChanged(String packageName, List<ShortcutInfo> shortcuts,
170                UserHandle user) {
171            List<ShortcutInfoCompat> shortcutInfoCompats = new ArrayList<>(shortcuts.size());
172            for (ShortcutInfo shortcutInfo : shortcuts) {
173                shortcutInfoCompats.add(new ShortcutInfoCompat(shortcutInfo));
174            }
175
176            mCallback.onShortcutsChanged(packageName, shortcutInfoCompats, user);
177        }
178    }
179
180    @Override
181    public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList(
182            @Nullable PackageUserKey packageUser) {
183        List<ShortcutConfigActivityInfo> result = new ArrayList<>();
184        if (packageUser != null && !packageUser.mUser.equals(Process.myUserHandle())) {
185            return result;
186        }
187        PackageManager pm = mContext.getPackageManager();
188        for (ResolveInfo info :
189                pm.queryIntentActivities(new Intent(Intent.ACTION_CREATE_SHORTCUT), 0)) {
190            if (packageUser == null || packageUser.mPackageName
191                    .equals(info.activityInfo.packageName)) {
192                result.add(new ShortcutConfigActivityInfoVL(info.activityInfo, pm));
193            }
194        }
195        return result;
196    }
197}
198
199