• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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.development;
18 
19 import android.app.AlertDialog;
20 import android.app.ListActivity;
21 import android.content.Context;
22 import android.content.pm.IPackageDeleteObserver;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.content.BroadcastReceiver;
26 import android.content.pm.PackageInfo;
27 import android.content.pm.PackageManager;
28 import android.net.Uri;
29 import android.os.Bundle;
30 import android.os.RemoteException;
31 import android.os.Handler;
32 import android.view.Menu;
33 import android.view.MenuItem;
34 import android.view.View;
35 import android.widget.ImageView;
36 import android.widget.ListView;
37 import android.widget.TextView;
38 
39 import java.text.Collator;
40 import java.util.ArrayList;
41 import java.util.Collections;
42 import java.util.Comparator;
43 import java.util.List;
44 
45 public class PackageBrowser extends ListActivity {
46     static class MyPackageInfo {
47         PackageInfo info;
48         String label;
49     }
50 
51     private PackageListAdapter mAdapter;
52     private List<MyPackageInfo> mPackageInfoList = new ArrayList<MyPackageInfo>();
53     private Handler mHandler;
54     private BroadcastReceiver mRegisteredReceiver;
55 
56     public class PackageListAdapter extends ArrayAdapter<MyPackageInfo> {
57 
PackageListAdapter(Context context)58         public PackageListAdapter(Context context) {
59             super(context, R.layout.package_list_item);
60             List<PackageInfo> pkgs = context.getPackageManager().getInstalledPackages(0);
61             for (int i=0; i<pkgs.size(); i++) {
62                 MyPackageInfo info = new MyPackageInfo();
63                 info.info = pkgs.get(i);
64                 info.label = info.info.applicationInfo.loadLabel(getPackageManager()).toString();
65                 mPackageInfoList.add(info);
66             }
67             if (mPackageInfoList != null) {
68                 Collections.sort(mPackageInfoList, sDisplayNameComparator);
69             }
70             setSource(mPackageInfoList);
71         }
72 
73         @Override
bindView(View view, MyPackageInfo info)74         public void bindView(View view, MyPackageInfo info) {
75             ImageView icon = (ImageView)view.findViewById(R.id.icon);
76             TextView name = (TextView)view.findViewById(R.id.name);
77             TextView description = (TextView)view.findViewById(R.id.description);
78             icon.setImageDrawable(info.info.applicationInfo.loadIcon(getPackageManager()));
79             name.setText(info.label);
80             description.setText(info.info.packageName);
81         }
82     }
83 
84     /**
85      * Receives notifications when applications are added/removed.
86      */
87     private class ApplicationsIntentReceiver extends BroadcastReceiver {
88         @Override
onReceive(Context context, Intent intent)89         public void onReceive(Context context, Intent intent) {
90             // todo: this is a bit brute force.  We should probably get the action and package name
91             //       from the intent and just add to or delete from the mPackageInfoList
92             setupAdapter();
93         }
94     }
95 
96     private final static Comparator<MyPackageInfo> sDisplayNameComparator
97             = new Comparator<MyPackageInfo>() {
98         public final int
99         compare(MyPackageInfo a, MyPackageInfo b) {
100             return collator.compare(a.label, b.label);
101         }
102 
103         private final Collator   collator = Collator.getInstance();
104     };
105 
106     @Override
onCreate(Bundle icicle)107     protected void onCreate(Bundle icicle) {
108         super.onCreate(icicle);
109         setupAdapter();
110         mHandler= new Handler();
111         registerIntentReceivers();
112     }
113 
114     @Override
onDestroy()115     protected void onDestroy() {
116         super.onDestroy();
117         if (mRegisteredReceiver != null) {
118             unregisterReceiver(mRegisteredReceiver);
119         }
120     }
121 
setupAdapter()122     private void setupAdapter() {
123         mAdapter = new PackageListAdapter(this);
124         setListAdapter(mAdapter);
125     }
126 
127     @Override
onCreateOptionsMenu(Menu menu)128     public boolean onCreateOptionsMenu(Menu menu) {
129         menu.add(0, 0, 0, "Delete package").setOnMenuItemClickListener(
130                 new MenuItem.OnMenuItemClickListener() {
131             public boolean onMenuItemClick(MenuItem item) {
132                 deletePackage();
133                 return true;
134             }
135         });
136         return true;
137     }
138 
deletePackage()139     private void deletePackage() {
140         final int curSelection = getSelectedItemPosition();
141         if (curSelection >= 0) {
142             // todo: verification dialog for package deletion
143             final MyPackageInfo packageInfo = mAdapter.itemForPosition(curSelection);
144             if (packageInfo != null) {
145                 getPackageManager().deletePackage(packageInfo.info.packageName,
146                                                   new IPackageDeleteObserver.Stub() {
147                     public void packageDeleted(String packageName, int returnCode)
148                             throws RemoteException {
149                         if (returnCode == PackageManager.DELETE_SUCCEEDED) {
150                             mPackageInfoList.remove(curSelection);
151                             mHandler.post(new Runnable() {
152                                     public void run() {
153                                         mAdapter.notifyDataSetChanged();
154                                     }
155                                 });
156 
157                             // todo: verification dialog for data directory
158                             final String dataPath = packageInfo.info.applicationInfo.dataDir;
159                             // todo: delete the data directory
160                         } else {
161                             mHandler.post(new Runnable() {
162                                     public void run() {
163                                         new AlertDialog.Builder(PackageBrowser.this)
164                                             .setTitle("Oops")
165                                             .setMessage("Could not delete package." +
166                                                 "  Maybe it is in /system/app rather than /data/app?")
167                                             .show();
168                                     }
169                                 });
170 
171                         }
172                     }
173                 },
174                                                   0);
175             }
176         }
177     }
178 
registerIntentReceivers()179     private void registerIntentReceivers() {
180         IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
181         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
182         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
183         filter.addDataScheme("package");
184         mRegisteredReceiver = new ApplicationsIntentReceiver();
185         registerReceiver(mRegisteredReceiver, filter);
186     }
187 
188     @Override
onListItemClick(ListView l, View v, int position, long id)189     protected void onListItemClick(ListView l, View v, int position, long id) {
190         MyPackageInfo info =
191             mAdapter.itemForPosition(position);
192         if (info != null) {
193             Intent intent = new Intent(
194                 null, Uri.fromParts("package", info.info.packageName, null));
195             intent.setClass(this, PackageSummary.class);
196             startActivity(intent);
197         }
198     }
199 }
200