19244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn/* 29244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * Copyright (C) 2008 The Android Open Source Project 39244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * 49244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 59244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * you may not use this file except in compliance with the License. 69244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * You may obtain a copy of the License at 79244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * 89244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 99244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * 109244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 119244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 129244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * See the License for the specific language governing permissions and 149244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn * limitations under the License. 159244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn */ 169244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 179244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornpackage com.android.settings; 189244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 199244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport java.text.Collator; 209244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport java.util.ArrayList; 219244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport java.util.Collections; 229244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport java.util.Comparator; 239244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport java.util.List; 249244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 259244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport com.android.settings.applications.AppViewHolder; 269244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 279244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.app.ActivityManagerNative; 289244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.app.ListActivity; 299244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.content.Context; 309244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.content.Intent; 319244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.content.pm.ApplicationInfo; 329244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.os.Build; 339244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.os.Bundle; 349244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.os.Process; 359244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.os.RemoteException; 369244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.provider.Settings; 379244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.view.LayoutInflater; 389244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.view.View; 399244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.view.ViewGroup; 409244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.widget.ArrayAdapter; 419244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornimport android.widget.ListView; 429244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 439244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackbornpublic class AppPicker extends ListActivity { 449244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn private AppListAdapter mAdapter; 459244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 469244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn @Override 479244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn protected void onCreate(Bundle icicle) { 489244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn super.onCreate(icicle); 499244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 509244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn mAdapter = new AppListAdapter(this); 519244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn if (mAdapter.getCount() <= 0) { 529244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn finish(); 539244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } else { 549244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn setListAdapter(mAdapter); 559244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 569244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 579244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 589244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn @Override 599244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn protected void onResume() { 609244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn super.onResume(); 619244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 629244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 639244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn @Override 649244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn protected void onStop() { 659244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn super.onStop(); 669244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 679244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 689244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn @Override 699244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn protected void onListItemClick(ListView l, View v, int position, long id) { 709244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn MyApplicationInfo app = mAdapter.getItem(position); 719244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn Intent intent = new Intent(); 729244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn if (app.info != null) intent.setAction(app.info.packageName); 739244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn setResult(RESULT_OK, intent); 749244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn finish(); 759244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 769244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 779244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn class MyApplicationInfo { 789244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn ApplicationInfo info; 799244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn CharSequence label; 809244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 819244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 829244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> { 839244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn private final List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>(); 849244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn private final LayoutInflater mInflater; 859244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 869244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn public AppListAdapter(Context context) { 879244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn super(context, 0); 889244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 899244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn List<ApplicationInfo> pkgs = context.getPackageManager().getInstalledApplications(0); 909244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn for (int i=0; i<pkgs.size(); i++) { 919244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn ApplicationInfo ai = pkgs.get(i); 929244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn if (ai.uid == Process.SYSTEM_UID) { 939244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn continue; 949244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 959244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn // On a user build, we only allow debugging of apps that 969244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn // are marked as debuggable. Otherwise (for platform development) 979244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn // we allow all apps. 989244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn if ((ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0 999244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn && "user".equals(Build.TYPE)) { 1009244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn continue; 1019244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 1029244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn MyApplicationInfo info = new MyApplicationInfo(); 1039244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn info.info = ai; 1049244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn info.label = info.info.loadLabel(getPackageManager()).toString(); 1059244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn mPackageInfoList.add(info); 1069244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 1079244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn Collections.sort(mPackageInfoList, sDisplayNameComparator); 1089244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn MyApplicationInfo info = new MyApplicationInfo(); 1099244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn info.label = context.getText(R.string.no_application); 1109244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn mPackageInfoList.add(0, info); 1119244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn addAll(mPackageInfoList); 1129244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 1139244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 1149244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn @Override 1159244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn public View getView(int position, View convertView, ViewGroup parent) { 1169244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn // A ViewHolder keeps references to children views to avoid unnecessary calls 1179244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn // to findViewById() on each row. 1189244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView); 1199244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn convertView = holder.rootView; 1209244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn MyApplicationInfo info = getItem(position); 1219244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn holder.appName.setText(info.label); 1229244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn if (info.info != null) { 1239244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn holder.appIcon.setImageDrawable(info.info.loadIcon(getPackageManager())); 1249244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn holder.appSize.setText(info.info.packageName); 1259244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } else { 1269244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn holder.appIcon.setImageDrawable(null); 1279244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn holder.appSize.setText(""); 1289244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 1299244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn holder.disabled.setVisibility(View.GONE); 1309244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn holder.checkBox.setVisibility(View.GONE); 1319244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn return convertView; 1329244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 1339244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 1349244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 1359244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn private final static Comparator<MyApplicationInfo> sDisplayNameComparator 1369244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn = new Comparator<MyApplicationInfo>() { 1379244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn public final int 1389244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn compare(MyApplicationInfo a, MyApplicationInfo b) { 1399244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn return collator.compare(a.label, b.label); 1409244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn } 1419244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn 1429244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn private final Collator collator = Collator.getInstance(); 1439244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn }; 1449244df4c6422931697a0cf6e327b15cd71b6d8c4Dianne Hackborn} 145