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