summaryrefslogtreecommitdiff
path: root/core/java/android/app/LauncherActivity.java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:31:44 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:31:44 -0800
commit9066cfe9886ac131c34d59ed0e2d287b0e3c0087 (patch)
treed88beb88001f2482911e3d28e43833b50e4b4e97 /core/java/android/app/LauncherActivity.java
parentd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (diff)
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/android/app/LauncherActivity.java')
-rw-r--r--core/java/android/app/LauncherActivity.java380
1 files changed, 380 insertions, 0 deletions
diff --git a/core/java/android/app/LauncherActivity.java b/core/java/android/app/LauncherActivity.java
new file mode 100644
index 000000000000..d6fcbb1a6aa7
--- /dev/null
+++ b/core/java/android/app/LauncherActivity.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2007 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 android.app;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.PaintDrawable;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.BaseAdapter;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * Displays a list of all activities which can be performed
+ * for a given intent. Launches when clicked.
+ *
+ */
+public abstract class LauncherActivity extends ListActivity {
+
+ Intent mIntent;
+ PackageManager mPackageManager;
+
+ /**
+ * An item in the list
+ */
+ public static class ListItem {
+ public CharSequence label;
+ //public CharSequence description;
+ public Drawable icon;
+ public String packageName;
+ public String className;
+
+ ListItem(PackageManager pm, ResolveInfo resolveInfo, IconResizer resizer) {
+ label = resolveInfo.loadLabel(pm);
+ if (label == null && resolveInfo.activityInfo != null) {
+ label = resolveInfo.activityInfo.name;
+ }
+
+ /*
+ if (resolveInfo.activityInfo != null &&
+ resolveInfo.activityInfo.applicationInfo != null) {
+ description = resolveInfo.activityInfo.applicationInfo.loadDescription(pm);
+ }
+ */
+
+ icon = resizer.createIconThumbnail(resolveInfo.loadIcon(pm));
+ packageName = resolveInfo.activityInfo.applicationInfo.packageName;
+ className = resolveInfo.activityInfo.name;
+ }
+
+ public ListItem() {
+ }
+ }
+
+ /**
+ * Adapter which shows the set of activities that can be performed for a given intent.
+ */
+ private class ActivityAdapter extends BaseAdapter implements Filterable {
+ private final Object lock = new Object();
+ private ArrayList<ListItem> mOriginalValues;
+
+ protected final LayoutInflater mInflater;
+
+ protected List<ListItem> mActivitiesList;
+
+ private Filter mFilter;
+
+ public ActivityAdapter() {
+ mInflater = (LayoutInflater) LauncherActivity.this.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ mActivitiesList = makeListItems();
+ }
+
+ public Intent intentForPosition(int position) {
+ if (mActivitiesList == null) {
+ return null;
+ }
+
+ Intent intent = new Intent(mIntent);
+ ListItem item = mActivitiesList.get(position);
+ intent.setClassName(item.packageName, item.className);
+ return intent;
+ }
+
+ public int getCount() {
+ return mActivitiesList != null ? mActivitiesList.size() : 0;
+ }
+
+ public Object getItem(int position) {
+ return position;
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View view;
+ if (convertView == null) {
+ view = mInflater.inflate(
+ com.android.internal.R.layout.activity_list_item_2, parent, false);
+ } else {
+ view = convertView;
+ }
+ bindView(view, mActivitiesList.get(position));
+ return view;
+ }
+
+ private void bindView(View view, ListItem item) {
+ TextView text = (TextView) view;
+ text.setText(item.label);
+ text.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null);
+ }
+
+ public Filter getFilter() {
+ if (mFilter == null) {
+ mFilter = new ArrayFilter();
+ }
+ return mFilter;
+ }
+
+ /**
+ * An array filters constrains the content of the array adapter with a prefix. Each
+ * item that does not start with the supplied prefix is removed from the list.
+ */
+ private class ArrayFilter extends Filter {
+ @Override
+ protected FilterResults performFiltering(CharSequence prefix) {
+ FilterResults results = new FilterResults();
+
+ if (mOriginalValues == null) {
+ synchronized (lock) {
+ mOriginalValues = new ArrayList<ListItem>(mActivitiesList);
+ }
+ }
+
+ if (prefix == null || prefix.length() == 0) {
+ synchronized (lock) {
+ ArrayList<ListItem> list = new ArrayList<ListItem>(mOriginalValues);
+ results.values = list;
+ results.count = list.size();
+ }
+ } else {
+ final String prefixString = prefix.toString().toLowerCase();
+
+ ArrayList<ListItem> values = mOriginalValues;
+ int count = values.size();
+
+ ArrayList<ListItem> newValues = new ArrayList<ListItem>(count);
+
+ for (int i = 0; i < count; i++) {
+ ListItem item = values.get(i);
+
+ String[] words = item.label.toString().toLowerCase().split(" ");
+ int wordCount = words.length;
+
+ for (int k = 0; k < wordCount; k++) {
+ final String word = words[k];
+
+ if (word.startsWith(prefixString)) {
+ newValues.add(item);
+ break;
+ }
+ }
+ }
+
+ results.values = newValues;
+ results.count = newValues.size();
+ }
+
+ return results;
+ }
+
+ @Override
+ protected void publishResults(CharSequence constraint, FilterResults results) {
+ //noinspection unchecked
+ mActivitiesList = (List<ListItem>) results.values;
+ if (results.count > 0) {
+ notifyDataSetChanged();
+ } else {
+ notifyDataSetInvalidated();
+ }
+ }
+ }
+ }
+
+ /**
+ * Utility class to resize icons to match default icon size.
+ */
+ public class IconResizer {
+ // Code is borrowed from com.android.launcher.Utilities.
+ private int mIconWidth = -1;
+ private int mIconHeight = -1;
+
+ private final Rect mOldBounds = new Rect();
+ private Canvas mCanvas = new Canvas();
+
+ public IconResizer() {
+ mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
+ Paint.FILTER_BITMAP_FLAG));
+
+ final Resources resources = LauncherActivity.this.getResources();
+ mIconWidth = mIconHeight = (int) resources.getDimension(
+ android.R.dimen.app_icon_size);
+ }
+
+ /**
+ * Returns a Drawable representing the thumbnail of the specified Drawable.
+ * The size of the thumbnail is defined by the dimension
+ * android.R.dimen.launcher_application_icon_size.
+ *
+ * This method is not thread-safe and should be invoked on the UI thread only.
+ *
+ * @param icon The icon to get a thumbnail of.
+ *
+ * @return A thumbnail for the specified icon or the icon itself if the
+ * thumbnail could not be created.
+ */
+ public Drawable createIconThumbnail(Drawable icon) {
+ int width = mIconWidth;
+ int height = mIconHeight;
+
+ final int iconWidth = icon.getIntrinsicWidth();
+ final int iconHeight = icon.getIntrinsicHeight();
+
+ if (icon instanceof PaintDrawable) {
+ PaintDrawable painter = (PaintDrawable) icon;
+ painter.setIntrinsicWidth(width);
+ painter.setIntrinsicHeight(height);
+ }
+
+ if (width > 0 && height > 0) {
+ if (width < iconWidth || height < iconHeight) {
+ final float ratio = (float) iconWidth / iconHeight;
+
+ if (iconWidth > iconHeight) {
+ height = (int) (width / ratio);
+ } else if (iconHeight > iconWidth) {
+ width = (int) (height * ratio);
+ }
+
+ final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
+ Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
+ final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
+ final Canvas canvas = mCanvas;
+ canvas.setBitmap(thumb);
+ // Copy the old bounds to restore them later
+ // If we were to do oldBounds = icon.getBounds(),
+ // the call to setBounds() that follows would
+ // change the same instance and we would lose the
+ // old bounds
+ mOldBounds.set(icon.getBounds());
+ final int x = (mIconWidth - width) / 2;
+ final int y = (mIconHeight - height) / 2;
+ icon.setBounds(x, y, x + width, y + height);
+ icon.draw(canvas);
+ icon.setBounds(mOldBounds);
+ icon = new BitmapDrawable(thumb);
+ } else if (iconWidth < width && iconHeight < height) {
+ final Bitmap.Config c = Bitmap.Config.ARGB_8888;
+ final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
+ final Canvas canvas = mCanvas;
+ canvas.setBitmap(thumb);
+ mOldBounds.set(icon.getBounds());
+ final int x = (width - iconWidth) / 2;
+ final int y = (height - iconHeight) / 2;
+ icon.setBounds(x, y, x + iconWidth, y + iconHeight);
+ icon.draw(canvas);
+ icon.setBounds(mOldBounds);
+ icon = new BitmapDrawable(thumb);
+ }
+ }
+
+ return icon;
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mPackageManager = getPackageManager();
+
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ setProgressBarIndeterminateVisibility(true);
+ setContentView(com.android.internal.R.layout.activity_list);
+
+
+ mIntent = new Intent(getTargetIntent());
+ mIntent.setComponent(null);
+ mAdapter = new ActivityAdapter();
+
+ setListAdapter(mAdapter);
+ getListView().setTextFilterEnabled(true);
+
+ setProgressBarIndeterminateVisibility(false);
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ Intent intent = ((ActivityAdapter)mAdapter).intentForPosition(position);
+
+ startActivity(intent);
+ }
+
+ /**
+ * Return the actual Intent for a specific position in our
+ * {@link android.widget.ListView}.
+ * @param position The item whose Intent to return
+ */
+ protected Intent intentForPosition(int position) {
+ ActivityAdapter adapter = (ActivityAdapter) mAdapter;
+ return adapter.intentForPosition(position);
+ }
+
+ /**
+ * Get the base intent to use when running
+ * {@link PackageManager#queryIntentActivities(Intent, int)}.
+ */
+ protected Intent getTargetIntent() {
+ return new Intent();
+ }
+
+ /**
+ * Perform the query to determine which results to show and return a list of them.
+ */
+ public List<ListItem> makeListItems() {
+ // Load all matching activities and sort correctly
+ List<ResolveInfo> list = mPackageManager.queryIntentActivities(mIntent,
+ /* no flags */ 0);
+ Collections.sort(list, new ResolveInfo.DisplayNameComparator(mPackageManager));
+
+ IconResizer resizer = new IconResizer();
+
+ ArrayList<ListItem> result = new ArrayList<ListItem>(list.size());
+ int listSize = list.size();
+ for (int i = 0; i < listSize; i++) {
+ ResolveInfo resolveInfo = list.get(i);
+ result.add(new ListItem(mPackageManager, resolveInfo, resizer));
+ }
+
+ return result;
+ }
+}