• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.development;
18 
19 import android.app.ListActivity;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.pm.ApplicationInfo;
23 import android.content.pm.PackageInfo;
24 import android.content.pm.PackageManager;
25 import android.os.Build;
26 import android.os.Bundle;
27 import android.os.Process;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.widget.ArrayAdapter;
32 import android.widget.ListView;
33 
34 import com.android.settings.R;
35 import com.android.settings.applications.AppViewHolder;
36 
37 import java.text.Collator;
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.Comparator;
41 import java.util.List;
42 
43 public class AppPicker extends ListActivity {
44     private AppListAdapter mAdapter;
45 
46     public static final String EXTRA_REQUESTIING_PERMISSION
47             = "com.android.settings.extra.REQUESTIING_PERMISSION";
48     public static final String EXTRA_DEBUGGABLE = "com.android.settings.extra.DEBUGGABLE";
49 
50     private String mPermissionName;
51     private boolean mDebuggableOnly;
52 
53     @Override
onCreate(Bundle icicle)54     protected void onCreate(Bundle icicle) {
55         super.onCreate(icicle);
56 
57         mPermissionName = getIntent().getStringExtra(EXTRA_REQUESTIING_PERMISSION);
58         mDebuggableOnly = getIntent().getBooleanExtra(EXTRA_DEBUGGABLE, false);
59 
60         mAdapter = new AppListAdapter(this);
61         if (mAdapter.getCount() <= 0) {
62             finish();
63         } else {
64             setListAdapter(mAdapter);
65         }
66     }
67 
68     @Override
onResume()69     protected void onResume() {
70         super.onResume();
71     }
72 
73     @Override
onStop()74     protected void onStop() {
75         super.onStop();
76     }
77 
78     @Override
onListItemClick(ListView l, View v, int position, long id)79     protected void onListItemClick(ListView l, View v, int position, long id) {
80         MyApplicationInfo app = mAdapter.getItem(position);
81         Intent intent = new Intent();
82         if (app.info != null) intent.setAction(app.info.packageName);
83         setResult(RESULT_OK, intent);
84         finish();
85     }
86 
87     class MyApplicationInfo {
88         ApplicationInfo info;
89         CharSequence label;
90     }
91 
92     public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
93         private final List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
94         private final LayoutInflater mInflater;
95 
AppListAdapter(Context context)96         public AppListAdapter(Context context) {
97             super(context, 0);
98             mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
99             List<ApplicationInfo> pkgs = context.getPackageManager().getInstalledApplications(0);
100             for (int i=0; i<pkgs.size(); i++) {
101                 ApplicationInfo ai = pkgs.get(i);
102                 if (ai.uid == Process.SYSTEM_UID) {
103                     continue;
104                 }
105 
106                 // Filter out apps that are not debuggable if required.
107                 if (mDebuggableOnly) {
108                     // On a user build, we only allow debugging of apps that
109                     // are marked as debuggable.  Otherwise (for platform development)
110                     // we allow all apps.
111                     if ((ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0
112                             && "user".equals(Build.TYPE)) {
113                         continue;
114                     }
115                 }
116 
117                 // Filter out apps that do not request the permission if required.
118                 if (mPermissionName != null) {
119                     boolean requestsPermission = false;
120                     try {
121                         PackageInfo pi = getPackageManager().getPackageInfo(ai.packageName,
122                                 PackageManager.GET_PERMISSIONS);
123                         if (pi.requestedPermissions == null) {
124                             continue;
125                         }
126                         for (String requestedPermission : pi.requestedPermissions) {
127                             if (requestedPermission.equals(mPermissionName)) {
128                                 requestsPermission = true;
129                                 break;
130                             }
131                         }
132                         if (!requestsPermission) {
133                             continue;
134                         }
135                     } catch (PackageManager.NameNotFoundException e) {
136                         continue;
137                     }
138                 }
139 
140                 MyApplicationInfo info = new MyApplicationInfo();
141                 info.info = ai;
142                 info.label = info.info.loadLabel(getPackageManager()).toString();
143                 mPackageInfoList.add(info);
144             }
145             Collections.sort(mPackageInfoList, sDisplayNameComparator);
146             MyApplicationInfo info = new MyApplicationInfo();
147             info.label = context.getText(R.string.no_application);
148             mPackageInfoList.add(0, info);
149             addAll(mPackageInfoList);
150         }
151 
152         @Override
getView(int position, View convertView, ViewGroup parent)153         public View getView(int position, View convertView, ViewGroup parent) {
154             // A ViewHolder keeps references to children views to avoid unnecessary calls
155             // to findViewById() on each row.
156             AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
157             convertView = holder.rootView;
158             MyApplicationInfo info = getItem(position);
159             holder.appName.setText(info.label);
160             if (info.info != null) {
161                 holder.appIcon.setImageDrawable(info.info.loadIcon(getPackageManager()));
162                 holder.summary.setText(info.info.packageName);
163             } else {
164                 holder.appIcon.setImageDrawable(null);
165                 holder.summary.setText("");
166             }
167             holder.disabled.setVisibility(View.GONE);
168             return convertView;
169         }
170     }
171 
172     private final static Comparator<MyApplicationInfo> sDisplayNameComparator
173             = new Comparator<MyApplicationInfo>() {
174         public final int
175         compare(MyApplicationInfo a, MyApplicationInfo b) {
176             return collator.compare(a.label, b.label);
177         }
178 
179         private final Collator collator = Collator.getInstance();
180     };
181 }
182