Home | History | Annotate | Download | only in compat
      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 
     17 package com.android.launcher3.compat;
     18 
     19 import android.content.ComponentName;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.pm.ApplicationInfo;
     23 import android.content.pm.LauncherActivityInfo;
     24 import android.content.pm.LauncherApps;
     25 import android.content.pm.PackageManager;
     26 import android.content.pm.ResolveInfo;
     27 import android.content.pm.ShortcutInfo;
     28 import android.graphics.Rect;
     29 import android.os.Bundle;
     30 import android.os.Process;
     31 import android.os.UserHandle;
     32 import android.support.annotation.NonNull;
     33 import android.support.annotation.Nullable;
     34 import android.util.ArrayMap;
     35 import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVL;
     36 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
     37 import com.android.launcher3.util.PackageUserKey;
     38 import java.util.ArrayList;
     39 import java.util.List;
     40 
     41 public class LauncherAppsCompatVL extends LauncherAppsCompat {
     42 
     43     protected final LauncherApps mLauncherApps;
     44     protected final Context mContext;
     45 
     46     private final ArrayMap<OnAppsChangedCallbackCompat, WrappedCallback> mCallbacks =
     47         new ArrayMap<>();
     48 
     49     LauncherAppsCompatVL(Context context) {
     50         mContext = context;
     51         mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
     52     }
     53 
     54     @Override
     55     public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
     56         return mLauncherApps.getActivityList(packageName, user);
     57     }
     58 
     59     @Override
     60     public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
     61         return mLauncherApps.resolveActivity(intent, user);
     62     }
     63 
     64     @Override
     65     public void startActivityForProfile(ComponentName component, UserHandle user,
     66             Rect sourceBounds, Bundle opts) {
     67         mLauncherApps.startMainActivity(component, user, sourceBounds, opts);
     68     }
     69 
     70     @Override
     71     public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) {
     72         final boolean isPrimaryUser = Process.myUserHandle().equals(user);
     73         if (!isPrimaryUser && (flags == 0)) {
     74             // We are looking for an installed app on a secondary profile. Prior to O, the only
     75             // entry point for work profiles is through the LauncherActivity.
     76             List<LauncherActivityInfo> activityList =
     77                     mLauncherApps.getActivityList(packageName, user);
     78             return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null;
     79         }
     80         try {
     81             ApplicationInfo info =
     82                     mContext.getPackageManager().getApplicationInfo(packageName, flags);
     83             // There is no way to check if the app is installed for managed profile. But for
     84             // primary profile, we can still have this check.
     85             if (isPrimaryUser && ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0)
     86                     || !info.enabled) {
     87                 return null;
     88             }
     89             return info;
     90         } catch (PackageManager.NameNotFoundException e) {
     91             // Package not found
     92             return null;
     93         }
     94     }
     95 
     96     @Override
     97     public void showAppDetailsForProfile(ComponentName component, UserHandle user,
     98             Rect sourceBounds, Bundle opts) {
     99         mLauncherApps.startAppDetailsActivity(component, user, sourceBounds, opts);
    100     }
    101 
    102     @Override
    103     public void addOnAppsChangedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
    104         WrappedCallback wrappedCallback = new WrappedCallback(callback);
    105         synchronized (mCallbacks) {
    106             mCallbacks.put(callback, wrappedCallback);
    107         }
    108         mLauncherApps.registerCallback(wrappedCallback);
    109     }
    110 
    111     @Override
    112     public void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) {
    113         final WrappedCallback wrappedCallback;
    114         synchronized (mCallbacks) {
    115             wrappedCallback = mCallbacks.remove(callback);
    116         }
    117         if (wrappedCallback != null) {
    118             mLauncherApps.unregisterCallback(wrappedCallback);
    119         }
    120     }
    121 
    122     @Override
    123     public boolean isPackageEnabledForProfile(String packageName, UserHandle user) {
    124         return mLauncherApps.isPackageEnabled(packageName, user);
    125     }
    126 
    127     @Override
    128     public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) {
    129         return mLauncherApps.isActivityEnabled(component, user);
    130     }
    131 
    132     private static class WrappedCallback extends LauncherApps.Callback {
    133         private final LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;
    134 
    135         public WrappedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
    136             mCallback = callback;
    137         }
    138 
    139         @Override
    140         public void onPackageRemoved(String packageName, UserHandle user) {
    141             mCallback.onPackageRemoved(packageName, user);
    142         }
    143 
    144         @Override
    145         public void onPackageAdded(String packageName, UserHandle user) {
    146             mCallback.onPackageAdded(packageName, user);
    147         }
    148 
    149         @Override
    150         public void onPackageChanged(String packageName, UserHandle user) {
    151             mCallback.onPackageChanged(packageName, user);
    152         }
    153 
    154         @Override
    155         public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
    156             mCallback.onPackagesAvailable(packageNames, user, replacing);
    157         }
    158 
    159         @Override
    160         public void onPackagesUnavailable(String[] packageNames, UserHandle user,
    161                 boolean replacing) {
    162             mCallback.onPackagesUnavailable(packageNames, user, replacing);
    163         }
    164 
    165         @Override
    166         public void onPackagesSuspended(String[] packageNames, UserHandle user) {
    167             mCallback.onPackagesSuspended(packageNames, user);
    168         }
    169 
    170         @Override
    171         public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
    172             mCallback.onPackagesUnsuspended(packageNames, user);
    173         }
    174 
    175         @Override
    176         public void onShortcutsChanged(@NonNull String packageName,
    177             @NonNull List<ShortcutInfo> shortcuts,
    178             @NonNull UserHandle user) {
    179             List<ShortcutInfoCompat> shortcutInfoCompats = new ArrayList<>(shortcuts.size());
    180             for (ShortcutInfo shortcutInfo : shortcuts) {
    181                 shortcutInfoCompats.add(new ShortcutInfoCompat(shortcutInfo));
    182             }
    183 
    184             mCallback.onShortcutsChanged(packageName, shortcutInfoCompats, user);
    185         }
    186     }
    187 
    188     @Override
    189     public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList(
    190             @Nullable PackageUserKey packageUser) {
    191         List<ShortcutConfigActivityInfo> result = new ArrayList<>();
    192         if (packageUser != null && !packageUser.mUser.equals(Process.myUserHandle())) {
    193             return result;
    194         }
    195         PackageManager pm = mContext.getPackageManager();
    196         for (ResolveInfo info :
    197                 pm.queryIntentActivities(new Intent(Intent.ACTION_CREATE_SHORTCUT), 0)) {
    198             if (packageUser == null || packageUser.mPackageName
    199                     .equals(info.activityInfo.packageName)) {
    200                 result.add(new ShortcutConfigActivityInfoVL(info.activityInfo, pm));
    201             }
    202         }
    203         return result;
    204     }
    205 }
    206 
    207