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 import com.android.launcher3.util.FlagOp;
     26 import com.android.launcher3.util.StringFilter;
     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 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) {
     69         if (mAppFilter != null && !mAppFilter.shouldShowApp(info.componentName)) {
     70             return;
     71         }
     72         if (findActivity(data, info.componentName, info.user)) {
     73             return;
     74         }
     75         data.add(info);
     76         added.add(info);
     77     }
     78 
     79     public void clear() {
     80         data.clear();
     81         // TODO: do we clear these too?
     82         added.clear();
     83         removed.clear();
     84         modified.clear();
     85     }
     86 
     87     public int size() {
     88         return data.size();
     89     }
     90 
     91     public AppInfo get(int index) {
     92         return data.get(index);
     93     }
     94 
     95     /**
     96      * Add the icons for the supplied apk called packageName.
     97      */
     98     public void addPackage(Context context, String packageName, UserHandleCompat user) {
     99         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
    100         final List<LauncherActivityInfoCompat> matches = launcherApps.getActivityList(packageName,
    101                 user);
    102 
    103         for (LauncherActivityInfoCompat info : matches) {
    104             add(new AppInfo(context, info, user, mIconCache));
    105         }
    106     }
    107 
    108     /**
    109      * Remove the apps for the given apk identified by packageName.
    110      */
    111     public void removePackage(String packageName, UserHandleCompat user) {
    112         final List<AppInfo> data = this.data;
    113         for (int i = data.size() - 1; i >= 0; i--) {
    114             AppInfo info = data.get(i);
    115             final ComponentName component = info.intent.getComponent();
    116             if (info.user.equals(user) && packageName.equals(component.getPackageName())) {
    117                 removed.add(info);
    118                 data.remove(i);
    119             }
    120         }
    121     }
    122 
    123     /**
    124      * Updates the apps for the given packageName and user based on {@param op}.
    125      */
    126     public void updatePackageFlags(StringFilter pkgFilter, UserHandleCompat user, FlagOp op) {
    127         final List<AppInfo> data = this.data;
    128         for (int i = data.size() - 1; i >= 0; i--) {
    129             AppInfo info = data.get(i);
    130             final ComponentName component = info.intent.getComponent();
    131             if (info.user.equals(user) && pkgFilter.matches(component.getPackageName())) {
    132                 info.isDisabled = op.apply(info.isDisabled);
    133                 modified.add(info);
    134             }
    135         }
    136     }
    137 
    138     public void updateIconsAndLabels(HashSet<String> packages, UserHandleCompat 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, UserHandleCompat user) {
    152         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
    153         final List<LauncherActivityInfoCompat> 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                 final ComponentName component = applicationInfo.intent.getComponent();
    161                 if (user.equals(applicationInfo.user)
    162                         && packageName.equals(component.getPackageName())) {
    163                     if (!findActivity(matches, component)) {
    164                         removed.add(applicationInfo);
    165                         data.remove(i);
    166                     }
    167                 }
    168             }
    169 
    170             // Find enabled activities and add them to the adapter
    171             // Also updates existing activities with new labels/icons
    172             for (final LauncherActivityInfoCompat info : matches) {
    173                 AppInfo applicationInfo = findApplicationInfoLocked(
    174                         info.getComponentName().getPackageName(), user,
    175                         info.getComponentName().getClassName());
    176                 if (applicationInfo == null) {
    177                     add(new AppInfo(context, info, user, mIconCache));
    178                 } else {
    179                     mIconCache.getTitleAndIcon(applicationInfo, info, true /* useLowResIcon */);
    180                     modified.add(applicationInfo);
    181                 }
    182             }
    183         } else {
    184             // Remove all data for this package.
    185             for (int i = data.size() - 1; i >= 0; i--) {
    186                 final AppInfo applicationInfo = data.get(i);
    187                 final ComponentName component = applicationInfo.intent.getComponent();
    188                 if (user.equals(applicationInfo.user)
    189                         && packageName.equals(component.getPackageName())) {
    190                     removed.add(applicationInfo);
    191                     mIconCache.remove(component, user);
    192                     data.remove(i);
    193                 }
    194             }
    195         }
    196     }
    197 
    198 
    199     /**
    200      * Returns whether <em>apps</em> contains <em>component</em>.
    201      */
    202     private static boolean findActivity(List<LauncherActivityInfoCompat> apps,
    203             ComponentName component) {
    204         for (LauncherActivityInfoCompat info : apps) {
    205             if (info.getComponentName().equals(component)) {
    206                 return true;
    207             }
    208         }
    209         return false;
    210     }
    211 
    212     /**
    213      * Query the launcher apps service for whether the supplied package has
    214      * MAIN/LAUNCHER activities in the supplied package.
    215      */
    216     static boolean packageHasActivities(Context context, String packageName,
    217             UserHandleCompat user) {
    218         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
    219         return launcherApps.getActivityList(packageName, user).size() > 0;
    220     }
    221 
    222     /**
    223      * Returns whether <em>apps</em> contains <em>component</em>.
    224      */
    225     private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
    226             UserHandleCompat user) {
    227         final int N = apps.size();
    228         for (int i = 0; i < N; i++) {
    229             final AppInfo info = apps.get(i);
    230             if (info.user.equals(user) && info.componentName.equals(component)) {
    231                 return true;
    232             }
    233         }
    234         return false;
    235     }
    236 
    237     /**
    238      * Find an ApplicationInfo object for the given packageName and className.
    239      */
    240     private AppInfo findApplicationInfoLocked(String packageName, UserHandleCompat user,
    241             String className) {
    242         for (AppInfo info: data) {
    243             final ComponentName component = info.intent.getComponent();
    244             if (user.equals(info.user) && packageName.equals(component.getPackageName())
    245                     && className.equals(component.getClassName())) {
    246                 return info;
    247             }
    248         }
    249         return null;
    250     }
    251 }
    252