blob: 72c6693b3187743e5f3f2f1247a9d22507197933 [file] [log] [blame]
Joe Onorato9c1289c2009-08-17 11:03:03 -04001/*
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
Daniel Sandler325dc232013-06-05 22:57:57 -040017package com.android.launcher3;
Joe Onorato9c1289c2009-08-17 11:03:03 -040018
19import android.content.ComponentName;
Joe Onorato9c1289c2009-08-17 11:03:03 -040020import android.content.Context;
Joe Onorato9c1289c2009-08-17 11:03:03 -040021
Kenny Guyed131872014-04-30 03:02:21 +010022import com.android.launcher3.compat.LauncherActivityInfoCompat;
23import com.android.launcher3.compat.LauncherAppsCompat;
24import com.android.launcher3.compat.UserHandleCompat;
25
Michael Jurka34c2e6c2013-12-13 16:07:45 +010026import java.util.ArrayList;
27import java.util.List;
28
Joe Onorato9c1289c2009-08-17 11:03:03 -040029
30/**
31 * Stores the list of all applications for the all apps view.
32 */
33class AllAppsList {
34 public static final int DEFAULT_APPLICATIONS_NUMBER = 42;
Chris Wren6d0dde02014-02-10 12:16:54 -050035
Joe Onorato9c1289c2009-08-17 11:03:03 -040036 /** The list off all apps. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020037 public ArrayList<AppInfo> data =
38 new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
Joe Onorato9c1289c2009-08-17 11:03:03 -040039 /** The list of apps that have been added since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020040 public ArrayList<AppInfo> added =
41 new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
Joe Onorato9c1289c2009-08-17 11:03:03 -040042 /** The list of apps that have been removed since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020043 public ArrayList<AppInfo> removed = new ArrayList<AppInfo>();
Joe Onorato9c1289c2009-08-17 11:03:03 -040044 /** The list of apps that have been modified since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020045 public ArrayList<AppInfo> modified = new ArrayList<AppInfo>();
Joe Onorato9c1289c2009-08-17 11:03:03 -040046
Joe Onorato0589f0f2010-02-08 13:44:00 -080047 private IconCache mIconCache;
48
Bjorn Bringert1307f632013-10-03 22:31:03 +010049 private AppFilter mAppFilter;
50
Joe Onorato9c1289c2009-08-17 11:03:03 -040051 /**
52 * Boring constructor.
53 */
Bjorn Bringert1307f632013-10-03 22:31:03 +010054 public AllAppsList(IconCache iconCache, AppFilter appFilter) {
Joe Onorato0589f0f2010-02-08 13:44:00 -080055 mIconCache = iconCache;
Bjorn Bringert1307f632013-10-03 22:31:03 +010056 mAppFilter = appFilter;
Joe Onorato9c1289c2009-08-17 11:03:03 -040057 }
58
59 /**
60 * Add the supplied ApplicationInfo objects to the list, and enqueue it into the
61 * list to broadcast when notify() is called.
Joe Onoratod65d08e2010-04-20 15:43:37 -040062 *
63 * If the app is already in the list, doesn't add it.
Joe Onorato9c1289c2009-08-17 11:03:03 -040064 */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020065 public void add(AppInfo info) {
Bjorn Bringert1307f632013-10-03 22:31:03 +010066 if (mAppFilter != null && !mAppFilter.shouldShowApp(info.componentName)) {
67 return;
68 }
Kenny Guyed131872014-04-30 03:02:21 +010069 if (findActivity(data, info.componentName, info.user)) {
Joe Onoratod65d08e2010-04-20 15:43:37 -040070 return;
71 }
Daniel Sandler054019d2010-04-15 16:28:40 -040072 data.add(info);
73 added.add(info);
Joe Onorato9c1289c2009-08-17 11:03:03 -040074 }
Bjorn Bringert1307f632013-10-03 22:31:03 +010075
Joe Onorato9c1289c2009-08-17 11:03:03 -040076 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
Michael Jurkaeadbfc52013-09-04 00:45:37 +020088 public AppInfo get(int index) {
Joe Onorato9c1289c2009-08-17 11:03:03 -040089 return data.get(index);
90 }
91
92 /**
93 * Add the icons for the supplied apk called packageName.
94 */
Kenny Guyed131872014-04-30 03:02:21 +010095 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);
Joe Onorato9c1289c2009-08-17 11:03:03 -040099
Sunny Goyalb50cc8c2014-10-06 16:23:56 -0700100 for (LauncherActivityInfoCompat info : matches) {
101 add(new AppInfo(context, info, user, mIconCache, null));
Joe Onorato9c1289c2009-08-17 11:03:03 -0400102 }
103 }
104
105 /**
106 * Remove the apps for the given apk identified by packageName.
107 */
Sunny Goyal1a745e82014-10-02 15:58:31 -0700108 public void removePackage(String packageName, UserHandleCompat user, boolean clearCache) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200109 final List<AppInfo> data = this.data;
Romain Guy5c16f3e2010-01-12 17:24:58 -0800110 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200111 AppInfo info = data.get(i);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400112 final ComponentName component = info.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100113 if (info.user.equals(user) && packageName.equals(component.getPackageName())) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400114 removed.add(info);
115 data.remove(i);
116 }
117 }
Sunny Goyal1a745e82014-10-02 15:58:31 -0700118 if (clearCache) {
119 mIconCache.remove(packageName, user);
120 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400121 }
Joe Onorato0589f0f2010-02-08 13:44:00 -0800122
Joe Onorato9c1289c2009-08-17 11:03:03 -0400123 /**
124 * Add and remove icons for this package which has been updated.
125 */
Kenny Guyed131872014-04-30 03:02:21 +0100126 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);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400130 if (matches.size() > 0) {
131 // Find disabled/removed activities and remove them from data and add them
132 // to the removed list.
Romain Guy5c16f3e2010-01-12 17:24:58 -0800133 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200134 final AppInfo applicationInfo = data.get(i);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400135 final ComponentName component = applicationInfo.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100136 if (user.equals(applicationInfo.user)
137 && packageName.equals(component.getPackageName())) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400138 if (!findActivity(matches, component)) {
139 removed.add(applicationInfo);
Kenny Guyed131872014-04-30 03:02:21 +0100140 mIconCache.remove(component, user);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400141 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
Sunny Goyalb50cc8c2014-10-06 16:23:56 -0700148 for (final LauncherActivityInfoCompat info : matches) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200149 AppInfo applicationInfo = findApplicationInfoLocked(
Kenny Guyed131872014-04-30 03:02:21 +0100150 info.getComponentName().getPackageName(), user,
Adam Cohen52a28412014-07-09 11:30:12 -0700151 info.getComponentName().getClassName());
Joe Onorato9c1289c2009-08-17 11:03:03 -0400152 if (applicationInfo == null) {
Kenny Guyed131872014-04-30 03:02:21 +0100153 add(new AppInfo(context, info, user, mIconCache, null));
Joe Onorato9c1289c2009-08-17 11:03:03 -0400154 } else {
Kenny Guyed131872014-04-30 03:02:21 +0100155 mIconCache.remove(applicationInfo.componentName, user);
Winson Chungc3eecff2011-07-11 17:44:15 -0700156 mIconCache.getTitleAndIcon(applicationInfo, info, null);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400157 modified.add(applicationInfo);
158 }
159 }
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700160 } else {
161 // Remove all data for this package.
162 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200163 final AppInfo applicationInfo = data.get(i);
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700164 final ComponentName component = applicationInfo.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100165 if (user.equals(applicationInfo.user)
166 && packageName.equals(component.getPackageName())) {
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700167 removed.add(applicationInfo);
Kenny Guyed131872014-04-30 03:02:21 +0100168 mIconCache.remove(component, user);
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700169 data.remove(i);
170 }
171 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400172 }
173 }
174
Joe Onorato9c1289c2009-08-17 11:03:03 -0400175
176 /**
177 * Returns whether <em>apps</em> contains <em>component</em>.
178 */
Kenny Guyed131872014-04-30 03:02:21 +0100179 private static boolean findActivity(List<LauncherActivityInfoCompat> apps,
180 ComponentName component) {
181 for (LauncherActivityInfoCompat info : apps) {
182 if (info.getComponentName().equals(component)) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400183 return true;
184 }
185 }
186 return false;
187 }
188
189 /**
Kenny Guyed131872014-04-30 03:02:21 +0100190 * 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 /**
Joe Onoratod65d08e2010-04-20 15:43:37 -0400200 * Returns whether <em>apps</em> contains <em>component</em>.
201 */
Kenny Guyed131872014-04-30 03:02:21 +0100202 private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
203 UserHandleCompat user) {
Joe Onoratod65d08e2010-04-20 15:43:37 -0400204 final int N = apps.size();
Kenny Guyed131872014-04-30 03:02:21 +0100205 for (int i = 0; i < N; i++) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200206 final AppInfo info = apps.get(i);
Kenny Guyed131872014-04-30 03:02:21 +0100207 if (info.user.equals(user) && info.componentName.equals(component)) {
Joe Onoratod65d08e2010-04-20 15:43:37 -0400208 return true;
209 }
210 }
211 return false;
212 }
213
214 /**
Joe Onorato9c1289c2009-08-17 11:03:03 -0400215 * Find an ApplicationInfo object for the given packageName and className.
216 */
Kenny Guyed131872014-04-30 03:02:21 +0100217 private AppInfo findApplicationInfoLocked(String packageName, UserHandleCompat user,
218 String className) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200219 for (AppInfo info: data) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400220 final ComponentName component = info.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100221 if (user.equals(info.user) && packageName.equals(component.getPackageName())
Joe Onorato9c1289c2009-08-17 11:03:03 -0400222 && className.equals(component.getClassName())) {
223 return info;
224 }
225 }
226 return null;
227 }
228}