summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/AllAppsList.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/AllAppsList.java')
-rw-r--r--src/com/android/launcher3/AllAppsList.java221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
new file mode 100644
index 000000000..e74dc2133
--- /dev/null
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+
+
+/**
+ * Stores the list of all applications for the all apps view.
+ */
+class AllAppsList {
+ public static final int DEFAULT_APPLICATIONS_NUMBER = 42;
+
+ /** The list off all apps. */
+ public ArrayList<ApplicationInfo> data =
+ new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER);
+ /** The list of apps that have been added since the last notify() call. */
+ public ArrayList<ApplicationInfo> added =
+ new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER);
+ /** The list of apps that have been removed since the last notify() call. */
+ public ArrayList<ApplicationInfo> removed = new ArrayList<ApplicationInfo>();
+ /** The list of apps that have been modified since the last notify() call. */
+ public ArrayList<ApplicationInfo> modified = new ArrayList<ApplicationInfo>();
+
+ private IconCache mIconCache;
+
+ /**
+ * Boring constructor.
+ */
+ public AllAppsList(IconCache iconCache) {
+ mIconCache = iconCache;
+ }
+
+ /**
+ * Add the supplied ApplicationInfo objects to the list, and enqueue it into the
+ * list to broadcast when notify() is called.
+ *
+ * If the app is already in the list, doesn't add it.
+ */
+ public void add(ApplicationInfo info) {
+ if (findActivity(data, info.componentName)) {
+ return;
+ }
+ data.add(info);
+ added.add(info);
+ }
+
+ public void clear() {
+ data.clear();
+ // TODO: do we clear these too?
+ added.clear();
+ removed.clear();
+ modified.clear();
+ }
+
+ public int size() {
+ return data.size();
+ }
+
+ public ApplicationInfo get(int index) {
+ return data.get(index);
+ }
+
+ /**
+ * Add the icons for the supplied apk called packageName.
+ */
+ public void addPackage(Context context, String packageName) {
+ final List<ResolveInfo> matches = findActivitiesForPackage(context, packageName);
+
+ if (matches.size() > 0) {
+ for (ResolveInfo info : matches) {
+ add(new ApplicationInfo(context.getPackageManager(), info, mIconCache, null));
+ }
+ }
+ }
+
+ /**
+ * Remove the apps for the given apk identified by packageName.
+ */
+ public void removePackage(String packageName) {
+ final List<ApplicationInfo> data = this.data;
+ for (int i = data.size() - 1; i >= 0; i--) {
+ ApplicationInfo info = data.get(i);
+ final ComponentName component = info.intent.getComponent();
+ if (packageName.equals(component.getPackageName())) {
+ removed.add(info);
+ data.remove(i);
+ }
+ }
+ // This is more aggressive than it needs to be.
+ mIconCache.flush();
+ }
+
+ /**
+ * Add and remove icons for this package which has been updated.
+ */
+ public void updatePackage(Context context, String packageName) {
+ final List<ResolveInfo> matches = findActivitiesForPackage(context, packageName);
+ if (matches.size() > 0) {
+ // Find disabled/removed activities and remove them from data and add them
+ // to the removed list.
+ for (int i = data.size() - 1; i >= 0; i--) {
+ final ApplicationInfo applicationInfo = data.get(i);
+ final ComponentName component = applicationInfo.intent.getComponent();
+ if (packageName.equals(component.getPackageName())) {
+ if (!findActivity(matches, component)) {
+ removed.add(applicationInfo);
+ mIconCache.remove(component);
+ data.remove(i);
+ }
+ }
+ }
+
+ // Find enabled activities and add them to the adapter
+ // Also updates existing activities with new labels/icons
+ int count = matches.size();
+ for (int i = 0; i < count; i++) {
+ final ResolveInfo info = matches.get(i);
+ ApplicationInfo applicationInfo = findApplicationInfoLocked(
+ info.activityInfo.applicationInfo.packageName,
+ info.activityInfo.name);
+ if (applicationInfo == null) {
+ add(new ApplicationInfo(context.getPackageManager(), info, mIconCache, null));
+ } else {
+ mIconCache.remove(applicationInfo.componentName);
+ mIconCache.getTitleAndIcon(applicationInfo, info, null);
+ modified.add(applicationInfo);
+ }
+ }
+ } else {
+ // Remove all data for this package.
+ for (int i = data.size() - 1; i >= 0; i--) {
+ final ApplicationInfo applicationInfo = data.get(i);
+ final ComponentName component = applicationInfo.intent.getComponent();
+ if (packageName.equals(component.getPackageName())) {
+ removed.add(applicationInfo);
+ mIconCache.remove(component);
+ data.remove(i);
+ }
+ }
+ }
+ }
+
+ /**
+ * Query the package manager for MAIN/LAUNCHER activities in the supplied package.
+ */
+ private static List<ResolveInfo> findActivitiesForPackage(Context context, String packageName) {
+ final PackageManager packageManager = context.getPackageManager();
+
+ final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+ mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ mainIntent.setPackage(packageName);
+
+ final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
+ return apps != null ? apps : new ArrayList<ResolveInfo>();
+ }
+
+ /**
+ * Returns whether <em>apps</em> contains <em>component</em>.
+ */
+ private static boolean findActivity(List<ResolveInfo> apps, ComponentName component) {
+ final String className = component.getClassName();
+ for (ResolveInfo info : apps) {
+ final ActivityInfo activityInfo = info.activityInfo;
+ if (activityInfo.name.equals(className)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns whether <em>apps</em> contains <em>component</em>.
+ */
+ private static boolean findActivity(ArrayList<ApplicationInfo> apps, ComponentName component) {
+ final int N = apps.size();
+ for (int i=0; i<N; i++) {
+ final ApplicationInfo info = apps.get(i);
+ if (info.componentName.equals(component)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Find an ApplicationInfo object for the given packageName and className.
+ */
+ private ApplicationInfo findApplicationInfoLocked(String packageName, String className) {
+ for (ApplicationInfo info: data) {
+ final ComponentName component = info.intent.getComponent();
+ if (packageName.equals(component.getPackageName())
+ && className.equals(component.getClassName())) {
+ return info;
+ }
+ }
+ return null;
+ }
+}