blob: c4315936cc79300ba11eaca44a1e54044e75a423 [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;
Sunny Goyal3bbbabc2016-03-15 09:16:30 -070025import com.android.launcher3.util.FlagOp;
Sunny Goyalda891c12016-03-18 18:29:24 -070026import com.android.launcher3.util.StringFilter;
Kenny Guyed131872014-04-30 03:02:21 +010027
Michael Jurka34c2e6c2013-12-13 16:07:45 +010028import java.util.ArrayList;
Sunny Goyal77919b92015-05-06 16:53:21 -070029import java.util.HashSet;
Michael Jurka34c2e6c2013-12-13 16:07:45 +010030import java.util.List;
31
Joe Onorato9c1289c2009-08-17 11:03:03 -040032
33/**
34 * Stores the list of all applications for the all apps view.
35 */
36class AllAppsList {
37 public static final int DEFAULT_APPLICATIONS_NUMBER = 42;
Chris Wren6d0dde02014-02-10 12:16:54 -050038
Joe Onorato9c1289c2009-08-17 11:03:03 -040039 /** The list off all apps. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020040 public ArrayList<AppInfo> data =
41 new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
Joe Onorato9c1289c2009-08-17 11:03:03 -040042 /** The list of apps that have been added since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020043 public ArrayList<AppInfo> added =
44 new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
Joe Onorato9c1289c2009-08-17 11:03:03 -040045 /** The list of apps that have been removed since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020046 public ArrayList<AppInfo> removed = new ArrayList<AppInfo>();
Joe Onorato9c1289c2009-08-17 11:03:03 -040047 /** The list of apps that have been modified since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020048 public ArrayList<AppInfo> modified = new ArrayList<AppInfo>();
Joe Onorato9c1289c2009-08-17 11:03:03 -040049
Joe Onorato0589f0f2010-02-08 13:44:00 -080050 private IconCache mIconCache;
51
Bjorn Bringert1307f632013-10-03 22:31:03 +010052 private AppFilter mAppFilter;
53
Joe Onorato9c1289c2009-08-17 11:03:03 -040054 /**
55 * Boring constructor.
56 */
Bjorn Bringert1307f632013-10-03 22:31:03 +010057 public AllAppsList(IconCache iconCache, AppFilter appFilter) {
Joe Onorato0589f0f2010-02-08 13:44:00 -080058 mIconCache = iconCache;
Bjorn Bringert1307f632013-10-03 22:31:03 +010059 mAppFilter = appFilter;
Joe Onorato9c1289c2009-08-17 11:03:03 -040060 }
61
62 /**
63 * Add the supplied ApplicationInfo objects to the list, and enqueue it into the
64 * list to broadcast when notify() is called.
Joe Onoratod65d08e2010-04-20 15:43:37 -040065 *
66 * If the app is already in the list, doesn't add it.
Joe Onorato9c1289c2009-08-17 11:03:03 -040067 */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020068 public void add(AppInfo info) {
Bjorn Bringert1307f632013-10-03 22:31:03 +010069 if (mAppFilter != null && !mAppFilter.shouldShowApp(info.componentName)) {
70 return;
71 }
Kenny Guyed131872014-04-30 03:02:21 +010072 if (findActivity(data, info.componentName, info.user)) {
Joe Onoratod65d08e2010-04-20 15:43:37 -040073 return;
74 }
Daniel Sandler054019d2010-04-15 16:28:40 -040075 data.add(info);
76 added.add(info);
Joe Onorato9c1289c2009-08-17 11:03:03 -040077 }
Bjorn Bringert1307f632013-10-03 22:31:03 +010078
Joe Onorato9c1289c2009-08-17 11:03:03 -040079 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
Michael Jurkaeadbfc52013-09-04 00:45:37 +020091 public AppInfo get(int index) {
Joe Onorato9c1289c2009-08-17 11:03:03 -040092 return data.get(index);
93 }
94
95 /**
96 * Add the icons for the supplied apk called packageName.
97 */
Kenny Guyed131872014-04-30 03:02:21 +010098 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);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400102
Sunny Goyalb50cc8c2014-10-06 16:23:56 -0700103 for (LauncherActivityInfoCompat info : matches) {
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800104 add(new AppInfo(context, info, user, mIconCache));
Joe Onorato9c1289c2009-08-17 11:03:03 -0400105 }
106 }
107
108 /**
109 * Remove the apps for the given apk identified by packageName.
110 */
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800111 public void removePackage(String packageName, UserHandleCompat user) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200112 final List<AppInfo> data = this.data;
Romain Guy5c16f3e2010-01-12 17:24:58 -0800113 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200114 AppInfo info = data.get(i);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400115 final ComponentName component = info.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100116 if (info.user.equals(user) && packageName.equals(component.getPackageName())) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400117 removed.add(info);
118 data.remove(i);
119 }
120 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400121 }
Joe Onorato0589f0f2010-02-08 13:44:00 -0800122
Kenny Guy44cba692016-01-21 19:50:02 +0000123 /**
Sunny Goyal3bbbabc2016-03-15 09:16:30 -0700124 * Updates the apps for the given packageName and user based on {@param op}.
Kenny Guy44cba692016-01-21 19:50:02 +0000125 */
Sunny Goyalda891c12016-03-18 18:29:24 -0700126 public void updatePackageFlags(StringFilter pkgFilter, UserHandleCompat user, FlagOp op) {
Kenny Guy44cba692016-01-21 19:50:02 +0000127 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();
Sunny Goyalda891c12016-03-18 18:29:24 -0700131 if (info.user.equals(user) && pkgFilter.matches(component.getPackageName())) {
Sunny Goyal3bbbabc2016-03-15 09:16:30 -0700132 info.isDisabled = op.apply(info.isDisabled);
Kenny Guy44cba692016-01-21 19:50:02 +0000133 modified.add(info);
134 }
135 }
136 }
137
Sunny Goyal77919b92015-05-06 16:53:21 -0700138 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
Joe Onorato9c1289c2009-08-17 11:03:03 -0400148 /**
149 * Add and remove icons for this package which has been updated.
150 */
Kenny Guyed131872014-04-30 03:02:21 +0100151 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);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400155 if (matches.size() > 0) {
156 // Find disabled/removed activities and remove them from data and add them
157 // to the removed list.
Romain Guy5c16f3e2010-01-12 17:24:58 -0800158 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200159 final AppInfo applicationInfo = data.get(i);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400160 final ComponentName component = applicationInfo.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100161 if (user.equals(applicationInfo.user)
162 && packageName.equals(component.getPackageName())) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400163 if (!findActivity(matches, component)) {
164 removed.add(applicationInfo);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400165 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
Sunny Goyalb50cc8c2014-10-06 16:23:56 -0700172 for (final LauncherActivityInfoCompat info : matches) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200173 AppInfo applicationInfo = findApplicationInfoLocked(
Kenny Guyed131872014-04-30 03:02:21 +0100174 info.getComponentName().getPackageName(), user,
Adam Cohen52a28412014-07-09 11:30:12 -0700175 info.getComponentName().getClassName());
Joe Onorato9c1289c2009-08-17 11:03:03 -0400176 if (applicationInfo == null) {
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800177 add(new AppInfo(context, info, user, mIconCache));
Joe Onorato9c1289c2009-08-17 11:03:03 -0400178 } else {
Sunny Goyal34b65272015-03-11 16:56:52 -0700179 mIconCache.getTitleAndIcon(applicationInfo, info, true /* useLowResIcon */);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400180 modified.add(applicationInfo);
181 }
182 }
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700183 } else {
184 // Remove all data for this package.
185 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200186 final AppInfo applicationInfo = data.get(i);
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700187 final ComponentName component = applicationInfo.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100188 if (user.equals(applicationInfo.user)
189 && packageName.equals(component.getPackageName())) {
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700190 removed.add(applicationInfo);
Kenny Guyed131872014-04-30 03:02:21 +0100191 mIconCache.remove(component, user);
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700192 data.remove(i);
193 }
194 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400195 }
196 }
197
Joe Onorato9c1289c2009-08-17 11:03:03 -0400198
199 /**
200 * Returns whether <em>apps</em> contains <em>component</em>.
201 */
Kenny Guyed131872014-04-30 03:02:21 +0100202 private static boolean findActivity(List<LauncherActivityInfoCompat> apps,
203 ComponentName component) {
204 for (LauncherActivityInfoCompat info : apps) {
205 if (info.getComponentName().equals(component)) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400206 return true;
207 }
208 }
209 return false;
210 }
211
212 /**
Kenny Guyed131872014-04-30 03:02:21 +0100213 * 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 /**
Joe Onoratod65d08e2010-04-20 15:43:37 -0400223 * Returns whether <em>apps</em> contains <em>component</em>.
224 */
Kenny Guyed131872014-04-30 03:02:21 +0100225 private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
226 UserHandleCompat user) {
Joe Onoratod65d08e2010-04-20 15:43:37 -0400227 final int N = apps.size();
Kenny Guyed131872014-04-30 03:02:21 +0100228 for (int i = 0; i < N; i++) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200229 final AppInfo info = apps.get(i);
Kenny Guyed131872014-04-30 03:02:21 +0100230 if (info.user.equals(user) && info.componentName.equals(component)) {
Joe Onoratod65d08e2010-04-20 15:43:37 -0400231 return true;
232 }
233 }
234 return false;
235 }
236
237 /**
Joe Onorato9c1289c2009-08-17 11:03:03 -0400238 * Find an ApplicationInfo object for the given packageName and className.
239 */
Kenny Guyed131872014-04-30 03:02:21 +0100240 private AppInfo findApplicationInfoLocked(String packageName, UserHandleCompat user,
241 String className) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200242 for (AppInfo info: data) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400243 final ComponentName component = info.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100244 if (user.equals(info.user) && packageName.equals(component.getPackageName())
Joe Onorato9c1289c2009-08-17 11:03:03 -0400245 && className.equals(component.getClassName())) {
246 return info;
247 }
248 }
249 return null;
250 }
251}