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