• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
AllAppsList(IconCache iconCache, AppFilter appFilter)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      */
add(AppInfo info)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 
clear()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 
size()85     public int size() {
86         return data.size();
87     }
88 
get(int index)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      */
addPackage(Context context, String packageName, UserHandleCompat user)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      */
removePackage(String packageName, UserHandleCompat user)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 
updateIconsAndLabels(HashSet<String> packages, UserHandleCompat user, ArrayList<AppInfo> outUpdates)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      */
updatePackage(Context context, String packageName, UserHandleCompat user)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      */
findActivity(List<LauncherActivityInfoCompat> apps, ComponentName component)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      */
packageHasActivities(Context context, String packageName, UserHandleCompat user)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      */
findActivity(ArrayList<AppInfo> apps, ComponentName component, UserHandleCompat user)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      */
findApplicationInfoLocked(String packageName, UserHandleCompat user, String className)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