Home | History | Annotate | Download | only in launcher3
      1 /*
      2  * Copyright (C) 2008 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;
     18 
     19 import android.content.ComponentName;
     20 import android.content.Context;
     21 
     22 import com.android.launcher3.compat.LauncherActivityInfoCompat;
     23 import com.android.launcher3.compat.LauncherAppsCompat;
     24 import com.android.launcher3.compat.UserHandleCompat;
     25 
     26 import java.util.ArrayList;
     27 import java.util.HashSet;
     28 import java.util.List;
     29 
     30 
     31 /**
     32  * Stores the list of all applications for the all apps view.
     33  */
     34 class AllAppsList {
     35     public static final int DEFAULT_APPLICATIONS_NUMBER = 42;
     36 
     37     /** The list off all apps. */
     38     public ArrayList<AppInfo> data =
     39             new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
     40     /** The list of apps that have been added since the last notify() call. */
     41     public ArrayList<AppInfo> added =
     42             new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
     43     /** The list of apps that have been removed since the last notify() call. */
     44     public ArrayList<AppInfo> removed = new ArrayList<AppInfo>();
     45     /** The list of apps that have been modified since the last notify() call. */
     46     public ArrayList<AppInfo> modified = new ArrayList<AppInfo>();
     47 
     48     private IconCache mIconCache;
     49 
     50     private AppFilter mAppFilter;
     51 
     52     /**
     53      * Boring constructor.
     54      */
     55     public AllAppsList(IconCache iconCache, AppFilter appFilter) {
     56         mIconCache = iconCache;
     57         mAppFilter = appFilter;
     58     }
     59 
     60     /**
     61      * Add the supplied ApplicationInfo objects to the list, and enqueue it into the
     62      * list to broadcast when notify() is called.
     63      *
     64      * If the app is already in the list, doesn't add it.
     65      */
     66     public void add(AppInfo info) {
     67         if (mAppFilter != null && !mAppFilter.shouldShowApp(info.componentName)) {
     68             return;
     69         }
     70         if (findActivity(data, info.componentName, info.user)) {
     71             return;
     72         }
     73         data.add(info);
     74         added.add(info);
     75     }
     76 
     77     public void clear() {
     78         data.clear();
     79         // TODO: do we clear these too?
     80         added.clear();
     81         removed.clear();
     82         modified.clear();
     83     }
     84 
     85     public int size() {
     86         return data.size();
     87     }
     88 
     89     public AppInfo get(int index) {
     90         return data.get(index);
     91     }
     92 
     93     /**
     94      * Add the icons for the supplied apk called packageName.
     95      */
     96     public void addPackage(Context context, String packageName, UserHandleCompat user) {
     97         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
     98         final List<LauncherActivityInfoCompat> matches = launcherApps.getActivityList(packageName,
     99                 user);
    100 
    101         for (LauncherActivityInfoCompat info : matches) {
    102             add(new AppInfo(context, info, user, mIconCache));
    103         }
    104     }
    105 
    106     /**
    107      * Remove the apps for the given apk identified by packageName.
    108      */
    109     public void removePackage(String packageName, UserHandleCompat user) {
    110         final List<AppInfo> data = this.data;
    111         for (int i = data.size() - 1; i >= 0; i--) {
    112             AppInfo info = data.get(i);
    113             final ComponentName component = info.intent.getComponent();
    114             if (info.user.equals(user) && packageName.equals(component.getPackageName())) {
    115                 removed.add(info);
    116                 data.remove(i);
    117             }
    118         }
    119     }
    120 
    121     public void updateIconsAndLabels(HashSet<String> packages, UserHandleCompat user,
    122             ArrayList<AppInfo> outUpdates) {
    123         for (AppInfo info : data) {
    124             if (info.user.equals(user) && packages.contains(info.componentName.getPackageName())) {
    125                 mIconCache.updateTitleAndIcon(info);
    126                 outUpdates.add(info);
    127             }
    128         }
    129     }
    130 
    131     /**
    132      * Add and remove icons for this package which has been updated.
    133      */
    134     public void updatePackage(Context context, String packageName, UserHandleCompat user) {
    135         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
    136         final List<LauncherActivityInfoCompat> matches = launcherApps.getActivityList(packageName,
    137                 user);
    138         if (matches.size() > 0) {
    139             // Find disabled/removed activities and remove them from data and add them
    140             // to the removed list.
    141             for (int i = data.size() - 1; i >= 0; i--) {
    142                 final AppInfo applicationInfo = data.get(i);
    143                 final ComponentName component = applicationInfo.intent.getComponent();
    144                 if (user.equals(applicationInfo.user)
    145                         && packageName.equals(component.getPackageName())) {
    146                     if (!findActivity(matches, component)) {
    147                         removed.add(applicationInfo);
    148                         data.remove(i);
    149                     }
    150                 }
    151             }
    152 
    153             // Find enabled activities and add them to the adapter
    154             // Also updates existing activities with new labels/icons
    155             for (final LauncherActivityInfoCompat info : matches) {
    156                 AppInfo applicationInfo = findApplicationInfoLocked(
    157                         info.getComponentName().getPackageName(), user,
    158                         info.getComponentName().getClassName());
    159                 if (applicationInfo == null) {
    160                     add(new AppInfo(context, info, user, mIconCache));
    161                 } else {
    162                     mIconCache.getTitleAndIcon(applicationInfo, info, true /* useLowResIcon */);
    163                     modified.add(applicationInfo);
    164                 }
    165             }
    166         } else {
    167             // Remove all data for this package.
    168             for (int i = data.size() - 1; i >= 0; i--) {
    169                 final AppInfo applicationInfo = data.get(i);
    170                 final ComponentName component = applicationInfo.intent.getComponent();
    171                 if (user.equals(applicationInfo.user)
    172                         && packageName.equals(component.getPackageName())) {
    173                     removed.add(applicationInfo);
    174                     mIconCache.remove(component, user);
    175                     data.remove(i);
    176                 }
    177             }
    178         }
    179     }
    180 
    181 
    182     /**
    183      * Returns whether <em>apps</em> contains <em>component</em>.
    184      */
    185     private static boolean findActivity(List<LauncherActivityInfoCompat> apps,
    186             ComponentName component) {
    187         for (LauncherActivityInfoCompat info : apps) {
    188             if (info.getComponentName().equals(component)) {
    189                 return true;
    190             }
    191         }
    192         return false;
    193     }
    194 
    195     /**
    196      * Query the launcher apps service for whether the supplied package has
    197      * MAIN/LAUNCHER activities in the supplied package.
    198      */
    199     static boolean packageHasActivities(Context context, String packageName,
    200             UserHandleCompat user) {
    201         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
    202         return launcherApps.getActivityList(packageName, user).size() > 0;
    203     }
    204 
    205     /**
    206      * Returns whether <em>apps</em> contains <em>component</em>.
    207      */
    208     private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
    209             UserHandleCompat user) {
    210         final int N = apps.size();
    211         for (int i = 0; i < N; i++) {
    212             final AppInfo info = apps.get(i);
    213             if (info.user.equals(user) && info.componentName.equals(component)) {
    214                 return true;
    215             }
    216         }
    217         return false;
    218     }
    219 
    220     /**
    221      * Find an ApplicationInfo object for the given packageName and className.
    222      */
    223     private AppInfo findApplicationInfoLocked(String packageName, UserHandleCompat user,
    224             String className) {
    225         for (AppInfo info: data) {
    226             final ComponentName component = info.intent.getComponent();
    227             if (user.equals(info.user) && packageName.equals(component.getPackageName())
    228                     && className.equals(component.getClassName())) {
    229                 return info;
    230             }
    231         }
    232         return null;
    233     }
    234 }
    235