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