• 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.ActionBar;
20 import android.app.ListActivity;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.ApplicationInfo;
24 import android.content.pm.PackageInfo;
25 import android.content.pm.PackageManager;
26 import android.os.Build;
27 import android.os.Bundle;
28 import android.os.Process;
29 import android.view.LayoutInflater;
30 import android.view.MenuItem;
31 import android.view.View;
32 import android.view.ViewGroup;
33 import android.widget.ArrayAdapter;
34 import android.widget.ListView;
35 
36 import java.text.Collator;
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.Comparator;
40 import java.util.List;
41 
42 public class AppPicker extends ListActivity {
43     private AppListAdapter mAdapter;
44 
45     public static final String EXTRA_REQUESTIING_PERMISSION
46             = "com.android.settings.extra.REQUESTIING_PERMISSION";
47     public static final String EXTRA_DEBUGGABLE = "com.android.settings.extra.DEBUGGABLE";
48     public static final String EXTRA_NON_SYSTEM = "com.android.settings.extra.NON_SYSTEM";
49     public static final String EXTRA_INCLUDE_NOTHING = "com.android.settings.extra.INCLUDE_NOTHING";
50 
51     public static final int RESULT_NO_MATCHING_APPS = -2;
52 
53     private String mPermissionName;
54     private boolean mDebuggableOnly;
55     private boolean mNonSystemOnly;
56     private boolean mIncludeNothing;
57 
58     @Override
onCreate(Bundle icicle)59     protected void onCreate(Bundle icicle) {
60         super.onCreate(icicle);
61 
62         ActionBar actionBar = getActionBar();
63         if (actionBar != null) {
64             actionBar.setDisplayHomeAsUpEnabled(true);
65         }
66 
67         mPermissionName = getIntent().getStringExtra(EXTRA_REQUESTIING_PERMISSION);
68         mDebuggableOnly = getIntent().getBooleanExtra(EXTRA_DEBUGGABLE, false);
69         mNonSystemOnly = getIntent().getBooleanExtra(EXTRA_NON_SYSTEM, false);
70         mIncludeNothing = getIntent().getBooleanExtra(EXTRA_INCLUDE_NOTHING, true);
71 
72         mAdapter = new AppListAdapter(this);
73         if (mAdapter.getCount() <= 0) {
74             setResult(RESULT_NO_MATCHING_APPS);
75             finish();
76         } else {
77             setListAdapter(mAdapter);
78         }
79     }
80 
81     @Override
onOptionsItemSelected(MenuItem item)82     public boolean onOptionsItemSelected(MenuItem item) {
83         if (item.getItemId() == android.R.id.home) {
84             handleBackPressed();
85             return true;
86         }
87         return super.onOptionsItemSelected(item);
88     }
89 
90     @Override
onListItemClick(ListView l, View v, int position, long id)91     protected void onListItemClick(ListView l, View v, int position, long id) {
92         MyApplicationInfo app = mAdapter.getItem(position);
93         Intent intent = new Intent();
94         if (app.info != null) intent.setAction(app.info.packageName);
95         setResult(RESULT_OK, intent);
96         finish();
97     }
98 
handleBackPressed()99     private void handleBackPressed() {
100         if (getFragmentManager().getBackStackEntryCount() > 1) {
101             super.onBackPressed();
102         } else {
103             setResult(RESULT_CANCELED);
104             finish();
105         }
106     }
107 
108     class MyApplicationInfo {
109         ApplicationInfo info;
110         CharSequence label;
111     }
112 
113     public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
114         private final List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
115         private final LayoutInflater mInflater;
116 
AppListAdapter(Context context)117         public AppListAdapter(Context context) {
118             super(context, 0);
119             mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
120             List<ApplicationInfo> pkgs = context.getPackageManager().getInstalledApplications(0);
121             for (int i=0; i<pkgs.size(); i++) {
122                 ApplicationInfo ai = pkgs.get(i);
123                 if (ai.uid == Process.SYSTEM_UID) {
124                     continue;
125                 }
126 
127                 // Filter out apps that are not debuggable if required.
128                 if (mDebuggableOnly) {
129                     // On a user build, we only allow debugging of apps that
130                     // are marked as debuggable.  Otherwise (for platform development)
131                     // we allow all apps.
132                     if ((ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0
133                             && "user".equals(Build.TYPE)) {
134                         continue;
135                     }
136                 }
137 
138                 // Filter out apps that are system apps if requested
139                 if (mNonSystemOnly && ai.isSystemApp()) {
140                     continue;
141                 }
142 
143                 // Filter out apps that do not request the permission if required.
144                 if (mPermissionName != null) {
145                     boolean requestsPermission = false;
146                     try {
147                         PackageInfo pi = getPackageManager().getPackageInfo(ai.packageName,
148                                 PackageManager.GET_PERMISSIONS);
149                         if (pi.requestedPermissions == null) {
150                             continue;
151                         }
152                         for (String requestedPermission : pi.requestedPermissions) {
153                             if (requestedPermission.equals(mPermissionName)) {
154                                 requestsPermission = true;
155                                 break;
156                             }
157                         }
158                         if (!requestsPermission) {
159                             continue;
160                         }
161                     } catch (PackageManager.NameNotFoundException e) {
162                         continue;
163                     }
164                 }
165 
166                 MyApplicationInfo info = new MyApplicationInfo();
167                 info.info = ai;
168                 info.label = info.info.loadLabel(getPackageManager()).toString();
169                 mPackageInfoList.add(info);
170             }
171             Collections.sort(mPackageInfoList, sDisplayNameComparator);
172             if (mIncludeNothing) {
173                 MyApplicationInfo info = new MyApplicationInfo();
174                 info.label = context.getText(com.android.settingslib.R.string.no_application);
175                 mPackageInfoList.add(0, info);
176             }
177             addAll(mPackageInfoList);
178         }
179 
180         @Override
getView(int position, View convertView, ViewGroup parent)181         public View getView(int position, View convertView, ViewGroup parent) {
182             // A ViewHolder keeps references to children views to avoid unnecessary calls
183             // to findViewById() on each row.
184             AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
185             convertView = holder.rootView;
186             MyApplicationInfo info = getItem(position);
187             holder.appName.setText(info.label);
188             if (info.info != null) {
189                 holder.appIcon.setImageDrawable(info.info.loadIcon(getPackageManager()));
190                 holder.summary.setText(info.info.packageName);
191             } else {
192                 holder.appIcon.setImageDrawable(null);
193                 holder.summary.setText("");
194             }
195             holder.disabled.setVisibility(View.GONE);
196             holder.widget.setVisibility(View.GONE);
197             return convertView;
198         }
199     }
200 
201     private final static Comparator<MyApplicationInfo> sDisplayNameComparator
202             = new Comparator<MyApplicationInfo>() {
203         public final int
204         compare(MyApplicationInfo a, MyApplicationInfo b) {
205             return collator.compare(a.label, b.label);
206         }
207 
208         private final Collator collator = Collator.getInstance();
209     };
210 }
211