blob: 5ed7a629a8a15c340ed3a136e8ea76a0930ee844 [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) {
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800101 add(new AppInfo(context, info, user, mIconCache));
Joe Onorato9c1289c2009-08-17 11:03:03 -0400102 }
103 }
104
105 /**
106 * Remove the apps for the given apk identified by packageName.
107 */
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800108 public void removePackage(String packageName, UserHandleCompat user) {
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 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400118 }
Joe Onorato0589f0f2010-02-08 13:44:00 -0800119
Joe Onorato9c1289c2009-08-17 11:03:03 -0400120 /**
121 * Add and remove icons for this package which has been updated.
122 */
Kenny Guyed131872014-04-30 03:02:21 +0100123 public void updatePackage(Context context, String packageName, UserHandleCompat user) {
124 final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
125 final List<LauncherActivityInfoCompat> matches = launcherApps.getActivityList(packageName,
126 user);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400127 if (matches.size() > 0) {
128 // Find disabled/removed activities and remove them from data and add them
129 // to the removed list.
Romain Guy5c16f3e2010-01-12 17:24:58 -0800130 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200131 final AppInfo applicationInfo = data.get(i);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400132 final ComponentName component = applicationInfo.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100133 if (user.equals(applicationInfo.user)
134 && packageName.equals(component.getPackageName())) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400135 if (!findActivity(matches, component)) {
136 removed.add(applicationInfo);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400137 data.remove(i);
138 }
139 }
140 }
141
142 // Find enabled activities and add them to the adapter
143 // Also updates existing activities with new labels/icons
Sunny Goyalb50cc8c2014-10-06 16:23:56 -0700144 for (final LauncherActivityInfoCompat info : matches) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200145 AppInfo applicationInfo = findApplicationInfoLocked(
Kenny Guyed131872014-04-30 03:02:21 +0100146 info.getComponentName().getPackageName(), user,
Adam Cohen52a28412014-07-09 11:30:12 -0700147 info.getComponentName().getClassName());
Joe Onorato9c1289c2009-08-17 11:03:03 -0400148 if (applicationInfo == null) {
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800149 add(new AppInfo(context, info, user, mIconCache));
Joe Onorato9c1289c2009-08-17 11:03:03 -0400150 } else {
Sunny Goyal4fbc3822015-02-18 16:46:50 -0800151 mIconCache.getTitleAndIcon(applicationInfo, info);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400152 modified.add(applicationInfo);
153 }
154 }
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700155 } else {
156 // Remove all data for this package.
157 for (int i = data.size() - 1; i >= 0; i--) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200158 final AppInfo applicationInfo = data.get(i);
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700159 final ComponentName component = applicationInfo.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100160 if (user.equals(applicationInfo.user)
161 && packageName.equals(component.getPackageName())) {
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700162 removed.add(applicationInfo);
Kenny Guyed131872014-04-30 03:02:21 +0100163 mIconCache.remove(component, user);
Dianne Hackborn2d86dfe2010-07-24 16:48:01 -0700164 data.remove(i);
165 }
166 }
Joe Onorato9c1289c2009-08-17 11:03:03 -0400167 }
168 }
169
Joe Onorato9c1289c2009-08-17 11:03:03 -0400170
171 /**
172 * Returns whether <em>apps</em> contains <em>component</em>.
173 */
Kenny Guyed131872014-04-30 03:02:21 +0100174 private static boolean findActivity(List<LauncherActivityInfoCompat> apps,
175 ComponentName component) {
176 for (LauncherActivityInfoCompat info : apps) {
177 if (info.getComponentName().equals(component)) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400178 return true;
179 }
180 }
181 return false;
182 }
183
184 /**
Kenny Guyed131872014-04-30 03:02:21 +0100185 * Query the launcher apps service for whether the supplied package has
186 * MAIN/LAUNCHER activities in the supplied package.
187 */
188 static boolean packageHasActivities(Context context, String packageName,
189 UserHandleCompat user) {
190 final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
191 return launcherApps.getActivityList(packageName, user).size() > 0;
192 }
193
194 /**
Joe Onoratod65d08e2010-04-20 15:43:37 -0400195 * Returns whether <em>apps</em> contains <em>component</em>.
196 */
Kenny Guyed131872014-04-30 03:02:21 +0100197 private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
198 UserHandleCompat user) {
Joe Onoratod65d08e2010-04-20 15:43:37 -0400199 final int N = apps.size();
Kenny Guyed131872014-04-30 03:02:21 +0100200 for (int i = 0; i < N; i++) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200201 final AppInfo info = apps.get(i);
Kenny Guyed131872014-04-30 03:02:21 +0100202 if (info.user.equals(user) && info.componentName.equals(component)) {
Joe Onoratod65d08e2010-04-20 15:43:37 -0400203 return true;
204 }
205 }
206 return false;
207 }
208
209 /**
Joe Onorato9c1289c2009-08-17 11:03:03 -0400210 * Find an ApplicationInfo object for the given packageName and className.
211 */
Kenny Guyed131872014-04-30 03:02:21 +0100212 private AppInfo findApplicationInfoLocked(String packageName, UserHandleCompat user,
213 String className) {
Michael Jurkaeadbfc52013-09-04 00:45:37 +0200214 for (AppInfo info: data) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400215 final ComponentName component = info.intent.getComponent();
Kenny Guyed131872014-04-30 03:02:21 +0100216 if (user.equals(info.user) && packageName.equals(component.getPackageName())
Joe Onorato9c1289c2009-08-17 11:03:03 -0400217 && className.equals(component.getClassName())) {
218 return info;
219 }
220 }
221 return null;
222 }
223}