ResolverActivity.java revision 589e6f960db7f3c208a218b7d035f01d0c8460ab
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.app;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R;
20e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackbornimport com.android.internal.content.PackageMonitor;
21e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn
22c587861fe8c59b7f112c333838630b54ab2b38afAdam Powellimport android.app.ActivityManager;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ActivityInfo;
28eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport android.content.pm.LabeledIntent;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
30c587861fe8c59b7f112c333838630b54ab2b38afAdam Powellimport android.content.pm.PackageManager.NameNotFoundException;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ResolveInfo;
32c587861fe8c59b7f112c333838630b54ab2b38afAdam Powellimport android.content.res.Resources;
33eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport android.graphics.drawable.Drawable;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PatternMatcher;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
382d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powellimport android.view.LayoutInflater;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
412d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powellimport android.widget.AdapterView;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.BaseAdapter;
43c587861fe8c59b7f112c333838630b54ab2b38afAdam Powellimport android.widget.Button;
44c587861fe8c59b7f112c333838630b54ab2b38afAdam Powellimport android.widget.GridView;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.ImageView;
462d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powellimport android.widget.ListView;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.TextView;
482d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashSet;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This activity is displayed when the system attempts to start an Intent for
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which there is more than one matching activity, allowing the user to decide
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which to go to.  It is not normally used directly by application developers.
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
61c587861fe8c59b7f112c333838630b54ab2b38afAdam Powellpublic class ResolverActivity extends AlertActivity implements AdapterView.OnItemClickListener {
62c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    private static final String TAG = "ResolverActivity";
63c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ResolveListAdapter mAdapter;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private PackageManager mPm;
66c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    private boolean mAlwaysUseOption;
67c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    private boolean mShowExtended;
68c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    private GridView mGrid;
69c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    private Button mAlwaysButton;
70c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    private Button mOnceButton;
71c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    private int mIconDpi;
72c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    private int mIconSize;
73589e6f960db7f3c208a218b7d035f01d0c8460abAdam Powell    private int mMaxColumns;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
75d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn    private boolean mRegistered;
76e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
77e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        @Override public void onSomePackagesChanged() {
78e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            mAdapter.handlePackagesChanged();
79e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        }
80e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn    };
81e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn
82905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn    private Intent makeMyIntent() {
83905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        Intent intent = new Intent(getIntent());
84905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        // The resolver activity is set to be hidden from recent tasks.
85905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        // we don't want this attribute to be propagated to the next activity
86905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        // being launched.  Note that if the original Intent also had this
87905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        // flag set, we are now losing it.  That should be a very rare case
88905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        // and we can live with this.
89905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        intent.setFlags(intent.getFlags()&~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
90905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        return intent;
91905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn    }
92905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onCreate(Bundle savedInstanceState) {
95905577f6345c014fc2489a8068ea967ba8c18012Dianne Hackborn        onCreate(savedInstanceState, makeMyIntent(),
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                getResources().getText(com.android.internal.R.string.whichApplication),
97d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton                null, null, true);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onCreate(Bundle savedInstanceState, Intent intent,
101d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton            CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
102bce6f8f249ff2b65df9ed790cc460053ab8eccecMike Lockwood            boolean alwaysUseOption) {
103c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onCreate(savedInstanceState);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPm = getPackageManager();
106c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        mAlwaysUseOption = alwaysUseOption;
107589e6f960db7f3c208a218b7d035f01d0c8460abAdam Powell        mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.setComponent(null);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AlertController.AlertParams ap = mAlertParams;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ap.mTitle = title;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
114d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn        mPackageMonitor.register(this, getMainLooper(), false);
115d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn        mRegistered = true;
116e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn
117c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
118c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        mIconDpi = am.getLauncherLargeIconDensity();
119c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        mIconSize = am.getLauncherLargeIconSize();
120c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
121d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton        mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList);
12202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        int count = mAdapter.getCount();
123bce6f8f249ff2b65df9ed790cc460053ab8eccecMike Lockwood        if (count > 1) {
124c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            ap.mView = getLayoutInflater().inflate(R.layout.resolver_grid, null);
125c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            mGrid = (GridView) ap.mView.findViewById(R.id.resolver_grid);
126c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            mGrid.setAdapter(mAdapter);
127c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            mGrid.setOnItemClickListener(this);
128c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            mGrid.setOnItemLongClickListener(new ItemLongClickListener());
129c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
130c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            if (alwaysUseOption) {
131c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                mGrid.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
132c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            }
133c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
134c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            resizeGrid();
13502eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        } else if (count == 1) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            startActivity(mAdapter.intentForPosition(0));
137d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn            mPackageMonitor.unregister();
138d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn            mRegistered = false;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            finish();
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
142c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            ap.mMessage = getResources().getText(R.string.noApplications);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setupAlert();
1462d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell
147c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        if (alwaysUseOption) {
148c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            final ViewGroup buttonLayout = (ViewGroup) findViewById(R.id.button_bar);
149c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            buttonLayout.setVisibility(View.VISIBLE);
150c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
151c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
152c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        }
153c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    }
154c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
155c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    void resizeGrid() {
156c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        final int itemCount = mAdapter.getCount();
157589e6f960db7f3c208a218b7d035f01d0c8460abAdam Powell        mGrid.setNumColumns(Math.min(itemCount, mMaxColumns));
158c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    }
159c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
160c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    Drawable getIcon(Resources res, int resId) {
161c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        Drawable result;
162c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        try {
163c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            result = res.getDrawableForDensity(resId, mIconDpi);
164c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        } catch (Resources.NotFoundException e) {
165c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            result = null;
166c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        }
167c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
168c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        return result;
169c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    }
170c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
171c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    Drawable loadIconForResolveInfo(ResolveInfo ri) {
172c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        Drawable dr;
173c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        try {
174c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            if (ri.resolvePackageName != null && ri.icon != 0) {
175c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                dr = getIcon(mPm.getResourcesForApplication(ri.resolvePackageName), ri.icon);
176c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                if (dr != null) {
177c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                    return dr;
178c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                }
179c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            }
180c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            final int iconRes = ri.getIconResource();
181c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            if (iconRes != 0) {
182c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                dr = getIcon(mPm.getResourcesForApplication(ri.activityInfo.packageName), iconRes);
183c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                if (dr != null) {
184c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                    return dr;
185c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                }
186c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            }
187c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        } catch (NameNotFoundException e) {
188c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            Log.e(TAG, "Couldn't find resources for package", e);
1892d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell        }
190c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        return ri.loadIcon(mPm);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
193e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn    @Override
194e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn    protected void onRestart() {
195e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        super.onRestart();
196d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn        if (!mRegistered) {
197d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn            mPackageMonitor.register(this, getMainLooper(), false);
198d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn            mRegistered = true;
199d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn        }
200e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        mAdapter.handlePackagesChanged();
201e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn    }
202e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn
203e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn    @Override
204e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn    protected void onStop() {
205e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        super.onStop();
206d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn        if (mRegistered) {
207d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn            mPackageMonitor.unregister();
208d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn            mRegistered = false;
209d44713a63d51ba7f186c775c2a32f3c2ce018037Dianne Hackborn        }
210e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn    }
211e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn
212c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    @Override
213c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
214c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        if (mAlwaysUseOption) {
215c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            final int checkedPos = mGrid.getCheckedItemPosition();
216c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            final boolean enabled = checkedPos != GridView.INVALID_POSITION;
217c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            mAlwaysButton.setEnabled(enabled);
218c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            mOnceButton.setEnabled(enabled);
219c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        } else {
220c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            startSelected(position, false);
221c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        }
222c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    }
223c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
224c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    public void onButtonClick(View v) {
225c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        final int id = v.getId();
226c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        startSelected(mGrid.getCheckedItemPosition(), id == R.id.button_always);
227c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        dismiss();
228c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    }
229c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
230c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    void startSelected(int which, boolean always) {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResolveInfo ri = mAdapter.resolveInfoForPosition(which);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = mAdapter.intentForPosition(which);
233c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        onIntentSelected(ri, intent, always);
23402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        finish();
23502eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23702eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood    protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
23802eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood        if (alwaysCheck) {
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Build a reasonable intent filter, based on what matched.
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IntentFilter filter = new IntentFilter();
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (intent.getAction() != null) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filter.addAction(intent.getAction());
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Set<String> categories = intent.getCategories();
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (categories != null) {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (String cat : categories) {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    filter.addCategory(cat);
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            filter.addCategory(Intent.CATEGORY_DEFAULT);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Uri data = intent.getData();
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String mimeType = intent.resolveType(this);
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mimeType != null) {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        filter.addDataType(mimeType);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (IntentFilter.MalformedMimeTypeException e) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Log.w("ResolverActivity", e);
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        filter = null;
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2655ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn            }
2665ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn            if (data != null && data.getScheme() != null) {
2675ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                // We need the data specification if there was no type,
2685ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                // OR if the scheme is not one of our magical "file:"
2695ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                // or "content:" schemes (see IntentFilter for the reason).
2705ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                if (cat != IntentFilter.MATCH_CATEGORY_TYPE
2715ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                        || (!"file".equals(data.getScheme())
2725ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                                && !"content".equals(data.getScheme()))) {
2735ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                    filter.addDataScheme(data.getScheme());
2745ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn
2755ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                    // Look through the resolved filter to determine which part
2765ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                    // of it matched the original Intent.
2775ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                    Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
2785ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                    if (aIt != null) {
2795ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                        while (aIt.hasNext()) {
2805ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                            IntentFilter.AuthorityEntry a = aIt.next();
2815ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                            if (a.match(data) >= 0) {
2825ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                                int port = a.getPort();
2835ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                                filter.addDataAuthority(a.getHost(),
2845ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                                        port >= 0 ? Integer.toString(port) : null);
2855ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                                break;
2865ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                            }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2895ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                    Iterator<PatternMatcher> pIt = ri.filter.pathsIterator();
2905ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                    if (pIt != null) {
2915ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                        String path = data.getPath();
2925ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                        while (path != null && pIt.hasNext()) {
2935ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                            PatternMatcher p = pIt.next();
2945ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                            if (p.match(path)) {
2955ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                                filter.addDataPath(p.getPath(), p.getType());
2965ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                                break;
2975ef402baafc4818ccdf2aaec5da9cf25dd1c0e12Dianne Hackborn                            }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (filter != null) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int N = mAdapter.mList.size();
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ComponentName[] set = new ComponentName[N];
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int bestMatch = 0;
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i=0; i<N; i++) {
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ResolveInfo r = mAdapter.mList.get(i).ri;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    set[i] = new ComponentName(r.activityInfo.packageName,
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            r.activityInfo.name);
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (r.match > bestMatch) bestMatch = r.match;
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                getPackageManager().addPreferredActivity(filter, bestMatch, set,
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        intent.getComponent());
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (intent != null) {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            startActivity(intent);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
323c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    void showAppDetails(ResolveInfo ri) {
324c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        Intent in = new Intent().setAction("android.settings.APPLICATION_DETAILS_SETTINGS")
325c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                .setData(Uri.fromParts("package", ri.activityInfo.packageName, null));
326c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell        startActivity(in);
327c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell    }
328c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final class DisplayResolveInfo {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ResolveInfo ri;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence displayLabel;
332eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        Drawable displayIcon;
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence extendedInfo;
334eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        Intent origIntent;
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
336eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        DisplayResolveInfo(ResolveInfo pri, CharSequence pLabel,
337eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                CharSequence pInfo, Intent pOrigIntent) {
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ri = pri;
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            displayLabel = pLabel;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            extendedInfo = pInfo;
341eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            origIntent = pOrigIntent;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final class ResolveListAdapter extends BaseAdapter {
346e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        private final Intent[] mInitialIntents;
347e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        private final List<ResolveInfo> mBaseResolveList;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Intent mIntent;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final LayoutInflater mInflater;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
351e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        private List<ResolveInfo> mCurrentResolveList;
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private List<DisplayResolveInfo> mList;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
354eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        public ResolveListAdapter(Context context, Intent intent,
355d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton                Intent[] initialIntents, List<ResolveInfo> rList) {
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIntent = new Intent(intent);
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIntent.setComponent(null);
358e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            mInitialIntents = initialIntents;
359e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            mBaseResolveList = rList;
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
361e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            rebuildList();
362e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        }
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
364e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        public void handlePackagesChanged() {
365c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            final int oldItemCount = getCount();
366e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            rebuildList();
367e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            notifyDataSetChanged();
368e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            if (mList.size() <= 0) {
369e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                // We no longer have any items...  just finish the activity.
370e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                finish();
371e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            }
372c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
373c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            final int newItemCount = getCount();
374c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            if (newItemCount != oldItemCount) {
375c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                resizeGrid();
376c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            }
377e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        }
378e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn
379e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn        private void rebuildList() {
380e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            if (mBaseResolveList != null) {
381e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                mCurrentResolveList = mBaseResolveList;
382e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            } else {
383e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                mCurrentResolveList = mPm.queryIntentActivities(
384e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                        mIntent, PackageManager.MATCH_DEFAULT_ONLY
385c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                        | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0));
386d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton            }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int N;
388e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn            if ((mCurrentResolveList != null) && ((N = mCurrentResolveList.size()) > 0)) {
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Only display the first matches that are either of equal
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // priority or have asked to be default options.
391e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                ResolveInfo r0 = mCurrentResolveList.get(0);
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i=1; i<N; i++) {
393e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                    ResolveInfo ri = mCurrentResolveList.get(i);
39443a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                    if (false) Log.v(
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "ResolveListActivity",
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r0.activityInfo.name + "=" +
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r0.priority + "/" + r0.isDefault + " vs " +
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ri.activityInfo.name + "=" +
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ri.priority + "/" + ri.isDefault);
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   if (r0.priority != ri.priority ||
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r0.isDefault != ri.isDefault) {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        while (i < N) {
403e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                            mCurrentResolveList.remove(i);
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            N--;
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (N > 1) {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ResolveInfo.DisplayNameComparator rComparator =
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            new ResolveInfo.DisplayNameComparator(mPm);
411e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                    Collections.sort(mCurrentResolveList, rComparator);
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
413eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
414eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                mList = new ArrayList<DisplayResolveInfo>();
415eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
416eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                // First put the initial items at the top.
417e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                if (mInitialIntents != null) {
418e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                    for (int i=0; i<mInitialIntents.length; i++) {
419e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                        Intent ii = mInitialIntents[i];
420eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        if (ii == null) {
421eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            continue;
422eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        }
423eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        ActivityInfo ai = ii.resolveActivityInfo(
424eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                                getPackageManager(), 0);
425eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        if (ai == null) {
426eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            Log.w("ResolverActivity", "No activity found for "
427eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                                    + ii);
428eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            continue;
429eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        }
430eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        ResolveInfo ri = new ResolveInfo();
431eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        ri.activityInfo = ai;
432eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        if (ii instanceof LabeledIntent) {
433eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            LabeledIntent li = (LabeledIntent)ii;
434eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            ri.resolvePackageName = li.getSourcePackage();
435eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            ri.labelRes = li.getLabelResource();
436eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            ri.nonLocalizedLabel = li.getNonLocalizedLabel();
437eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            ri.icon = li.getIconResource();
438eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        }
439eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        mList.add(new DisplayResolveInfo(ri,
440eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                                ri.loadLabel(getPackageManager()), null, ii));
441eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    }
442eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                }
443eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Check for applications with same name and use application name or
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // package name if necessary
446e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                r0 = mCurrentResolveList.get(0);
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int start = 0;
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                CharSequence r0Label =  r0.loadLabel(mPm);
449c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                mShowExtended = false;
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 1; i < N; i++) {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (r0Label == null) {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r0Label = r0.activityInfo.packageName;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
454e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                    ResolveInfo ri = mCurrentResolveList.get(i);
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    CharSequence riLabel = ri.loadLabel(mPm);
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (riLabel == null) {
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        riLabel = ri.activityInfo.packageName;
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (riLabel.equals(r0Label)) {
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
462e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                    processGroup(mCurrentResolveList, start, (i-1), r0, r0Label);
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r0 = ri;
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r0Label = riLabel;
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    start = i;
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Process last group
468e8f2c7ff5abe339061f1823362e12b912c430c1aDianne Hackborn                processGroup(mCurrentResolveList, start, (N-1), r0, r0Label);
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void processGroup(List<ResolveInfo> rList, int start, int end, ResolveInfo ro,
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                CharSequence roLabel) {
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Process labels from start to i
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int num = end - start+1;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (num == 1) {
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // No duplicate labels. Use label for entry at start
478eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                mList.add(new DisplayResolveInfo(ro, roLabel, null, null));
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
480c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                mShowExtended = true;
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                boolean usePkg = false;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                CharSequence startApp = ro.activityInfo.applicationInfo.loadLabel(mPm);
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (startApp == null) {
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    usePkg = true;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!usePkg) {
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Use HashSet to track duplicates
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    HashSet<CharSequence> duplicates =
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        new HashSet<CharSequence>();
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    duplicates.add(startApp);
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (int j = start+1; j <= end ; j++) {
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ResolveInfo jRi = rList.get(j);
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        CharSequence jApp = jRi.activityInfo.applicationInfo.loadLabel(mPm);
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if ( (jApp == null) || (duplicates.contains(jApp))) {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            usePkg = true;
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            duplicates.add(jApp);
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Clear HashSet for later use
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    duplicates.clear();
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int k = start; k <= end; k++) {
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ResolveInfo add = rList.get(k);
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (usePkg) {
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Use application name for all entries from start to end-1
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mList.add(new DisplayResolveInfo(add, roLabel,
509eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                                add.activityInfo.packageName, null));
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Use package name for all entries from start to end-1
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mList.add(new DisplayResolveInfo(add, roLabel,
513eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                                add.activityInfo.applicationInfo.loadLabel(mPm), null));
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ResolveInfo resolveInfoForPosition(int position) {
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mList == null) {
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mList.get(position).ri;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Intent intentForPosition(int position) {
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mList == null) {
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
532eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            DisplayResolveInfo dri = mList.get(position);
533eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
534eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            Intent intent = new Intent(dri.origIntent != null
535eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    ? dri.origIntent : mIntent);
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
538eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            ActivityInfo ai = dri.ri.activityInfo;
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.setComponent(new ComponentName(
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ai.applicationInfo.packageName, ai.name));
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return intent;
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getCount() {
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mList != null ? mList.size() : 0;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Object getItem(int position) {
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return position;
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public long getItemId(int position) {
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return position;
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public View getView(int position, View convertView, ViewGroup parent) {
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View view;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (convertView == null) {
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                view = mInflater.inflate(
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.layout.resolve_list_item, parent, false);
561c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell
562c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                // Fix the icon size even if we have different sized resources
563c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                ImageView icon = (ImageView)view.findViewById(R.id.icon);
564c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams();
565c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                lp.width = lp.height = mIconSize;
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                view = convertView;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bindView(view, mList.get(position));
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return view;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final void bindView(View view, DisplayResolveInfo info) {
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TextView text = (TextView)view.findViewById(com.android.internal.R.id.text1);
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TextView text2 = (TextView)view.findViewById(com.android.internal.R.id.text2);
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ImageView icon = (ImageView)view.findViewById(R.id.icon);
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            text.setText(info.displayLabel);
578c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            if (mShowExtended) {
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                text2.setVisibility(View.VISIBLE);
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                text2.setText(info.extendedInfo);
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                text2.setVisibility(View.GONE);
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
584eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            if (info.displayIcon == null) {
585c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell                info.displayIcon = loadIconForResolveInfo(info.ri);
586eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            }
587eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            icon.setImageDrawable(info.displayIcon);
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5912d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell    class ItemLongClickListener implements AdapterView.OnItemLongClickListener {
5922d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell
5932d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell        @Override
5942d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
5952d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell            ResolveInfo ri = mAdapter.resolveInfoForPosition(position);
596c587861fe8c59b7f112c333838630b54ab2b38afAdam Powell            showAppDetails(ri);
5972d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell            return true;
5982d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell        }
5992d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell
6002d80962b2e93ae4e59d0197487bd0f6aad4cf26eAdam Powell    }
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
603