blob: 3b25dca34c57fcb7c73b26096892de8edd29e309 [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;
Sunny Goyal77919b92015-05-06 16:53:21 -070027import java.util.HashSet;
Michael Jurka34c2e6c2013-12-13 16:07:45 +010028import java.util.List;
29
Joe Onorato9c1289c2009-08-17 11:03:03 -040030
31/**
32 * Stores the list of all applications for the all apps view.
33 */
34class AllAppsList {
35 public static final int DEFAULT_APPLICATIONS_NUMBER = 42;
Chris Wren6d0dde02014-02-10 12:16:54 -050036
Joe Onorato9c1289c2009-08-17 11:03:03 -040037 /** The list off all apps. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020038 public ArrayList<AppInfo> data =
39 new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
Joe Onorato9c1289c2009-08-17 11:03:03 -040040 /** The list of apps that have been added since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020041 public ArrayList<AppInfo> added =
42 new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
Joe Onorato9c1289c2009-08-17 11:03:03 -040043 /** The list of apps that have been removed since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020044 public ArrayList<AppInfo> removed = new ArrayList<AppInfo>();
Joe Onorato9c1289c2009-08-17 11:03:03 -040045 /** The list of apps that have been modified since the last notify() call. */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020046 public ArrayList<AppInfo> modified = new ArrayList<AppInfo>();
Joe Onorato9c1289c2009-08-17 11:03:03 -040047
Joe Onorato0589f0f2010-02-08 13:44:00 -080048 private IconCache mIconCache;
49
Bjorn Bringert1307f632013-10-03 22:31:03 +010050 private AppFilter mAppFilter;
51
Joe Onorato9c1289c2009-08-17 11:03:03 -040052 /**
53 * Boring constructor.
54 */
Bjorn Bringert1307f632013-10-03 22:31:03 +010055 public AllAppsList(IconCache iconCache, AppFilter appFilter) {
Joe Onorato0589f0f2010-02-08 13:44:00 -080056 mIconCache = iconCache;
Bjorn Bringert1307f632013-10-03 22:31:03 +010057 mAppFilter = appFilter;
Joe Onorato9c1289c2009-08-17 11:03:03 -040058 }
59
60 /**
61 * Add the supplied ApplicationInfo objects to the list, and enqueue it into the
62 * list to broadcast when notify() is called.
Joe Onoratod65d08e2010-04-20 15:43:37 -040063 *
64 * If the app is already in the list, doesn't add it.
Joe Onorato9c1289c2009-08-17 11:03:03 -040065 */
Michael Jurkaeadbfc52013-09-04 00:45:37 +020066 public void add(AppInfo info) {
Bjorn Bringert1307f632013-10-03 22:31:03 +010067 if (mAppFilter != null && !mAppFilter.shouldShowApp(info.componentName)) {
68 return;
69 }
Kenny Guyed131872014-04-30 03:02:21 +010070 if (findActivity(data, info.componentName, info.user)) {
Joe Onoratod65d08e2010-04-20 15:43:37 -040071 return;
72 }
Daniel Sandler054019d2010-04-15 16:28:40 -040073 data.add(info);
74 added.add(info);
Joe Onorato9c1289c2009-08-17 11:03:03 -040075 }
Bjorn Bringert1307f632013-10-03 22:31:03 +010076
Joe Onorato9c1289c2009-08-17 11:03:03 -040077 public void clear() {
78 data.clear();
79 // TODO: do we clear these too?
80 added.clear();
81 removed.clear();
82 modified.clear();
83 }
84
85 public int size() {
86 return data.size();
87 }
88
Michael Jurkaeadbfc52013-09-04 00:45:37 +020089 public AppInfo get(int index) {
Joe Onorato9c1289c2009-08-17 11:03:03 -040090 return data.get(index);
91 }
92
93 /**
94 * Add the icons for the supplied apk called packageName.
95 */
Kenny Guyed131872014-04-30 03:02:21 +010096 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);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400100
Sunny Goyalb50cc8c2014-10-06 16:23:56 -0700101 for (LauncherActivityInfoCompat info : matches) {
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800102 add(new AppInfo(context, info, user, mIconCache));
Joe Onorato9c1289c2009-08-17 11:03:03 -0400103 }
104 }
105
106 /**
107 * Remove the apps for the given apk identified by packageName.
108 */
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800109 public void removePackage(String packageName, UserHandleCompat user) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200110 final List<AppInfo> data = this.data;
Romain Guy5c16f3e2010-01-12 17:24:58 -0800111 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200112 AppInfo info = data.get(i);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400113 final ComponentName component = info.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100114 if (info.user.equals(user) && packageName.equals(component.getPackageName())) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400115 removed.add(info);
116 data.remove(i);
117 }
118 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400119 }
Joe Onorato0589f0f2010-02-08 13:44:00 -0800120
Sunny Goyal77919b92015-05-06 16:53:21 -0700121 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
Joe Onorato9c1289c2009-08-17 11:03:03 -0400131 /**
132 * Add and remove icons for this package which has been updated.
133 */
Kenny Guyed131872014-04-30 03:02:21 +0100134 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);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400138 if (matches.size() > 0) {
139 // Find disabled/removed activities and remove them from data and add them
140 // to the removed list.
Romain Guy5c16f3e2010-01-12 17:24:58 -0800141 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200142 final AppInfo applicationInfo = data.get(i);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400143 final ComponentName component = applicationInfo.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100144 if (user.equals(applicationInfo.user)
145 && packageName.equals(component.getPackageName())) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400146 if (!findActivity(matches, component)) {
147 removed.add(applicationInfo);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400148 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
Sunny Goyalb50cc8c2014-10-06 16:23:56 -0700155 for (final LauncherActivityInfoCompat info : matches) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200156 AppInfo applicationInfo = findApplicationInfoLocked(
Kenny Guyed131872014-04-30 03:02:21 +0100157 info.getComponentName().getPackageName(), user,
Adam Cohen52a28412014-07-09 11:30:12 -0700158 info.getComponentName().getClassName());
Joe Onorato9c1289c2009-08-17 11:03:03 -0400159 if (applicationInfo == null) {
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800160 add(new AppInfo(context, info, user, mIconCache));
Joe Onorato9c1289c2009-08-17 11:03:03 -0400161 } else {
Sunny Goyal34b65272015-03-11 16:56:52 -0700162 mIconCache.getTitleAndIcon(applicationInfo, info, true /* useLowResIcon */);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400163 modified.add(applicationInfo);
164 }
165 }
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700166 } else {
167 // Remove all data for this package.
168 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200169 final AppInfo applicationInfo = data.get(i);
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700170 final ComponentName component = applicationInfo.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100171 if (user.equals(applicationInfo.user)
172 && packageName.equals(component.getPackageName())) {
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700173 removed.add(applicationInfo);
Kenny Guyed131872014-04-30 03:02:21 +0100174 mIconCache.remove(component, user);
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700175 data.remove(i);
176 }
177 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400178 }
179 }
180
Joe Onorato9c1289c2009-08-17 11:03:03 -0400181
182 /**
183 * Returns whether <em>apps</em> contains <em>component</em>.
184 */
Kenny Guyed131872014-04-30 03:02:21 +0100185 private static boolean findActivity(List<LauncherActivityInfoCompat> apps,
186 ComponentName component) {
187 for (LauncherActivityInfoCompat info : apps) {
188 if (info.getComponentName().equals(component)) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400189 return true;
190 }
191 }
192 return false;
193 }
194
195 /**
Kenny Guyed131872014-04-30 03:02:21 +0100196 * Query the launcher apps service for whether the supplied package has
197 * MAIN/LAUNCHER activities in the supplied package.
198 */
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 /**
Joe Onoratod65d08e2010-04-20 15:43:37 -0400206 * Returns whether <em>apps</em> contains <em>component</em>.
207 */
Kenny Guyed131872014-04-30 03:02:21 +0100208 private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
209 UserHandleCompat user) {
Joe Onoratod65d08e2010-04-20 15:43:37 -0400210 final int N = apps.size();
Kenny Guyed131872014-04-30 03:02:21 +0100211 for (int i = 0; i < N; i++) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200212 final AppInfo info = apps.get(i);
Kenny Guyed131872014-04-30 03:02:21 +0100213 if (info.user.equals(user) && info.componentName.equals(component)) {
Joe Onoratod65d08e2010-04-20 15:43:37 -0400214 return true;
215 }
216 }
217 return false;
218 }
219
220 /**
Joe Onorato9c1289c2009-08-17 11:03:03 -0400221 * Find an ApplicationInfo object for the given packageName and className.
222 */
Kenny Guyed131872014-04-30 03:02:21 +0100223 private AppInfo findApplicationInfoLocked(String packageName, UserHandleCompat user,
224 String className) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200225 for (AppInfo info: data) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400226 final ComponentName component = info.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100227 if (user.equals(info.user) && packageName.equals(component.getPackageName())
Joe Onorato9c1289c2009-08-17 11:03:03 -0400228 && className.equals(component.getClassName())) {
229 return info;
230 }
231 }
232 return null;
233 }
234}