• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2007, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 package com.android.packageinstaller;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.Intent;
26 import android.content.pm.ActivityInfo;
27 import android.content.pm.ApplicationInfo;
28 import android.content.pm.PackageManager;
29 import android.content.pm.PackageManager.NameNotFoundException;
30 import android.content.pm.ResolveInfo;
31 import android.graphics.drawable.Drawable;
32 import android.net.Uri;
33 import android.os.Bundle;
34 import android.os.UserManager;
35 import android.util.Log;
36 import android.view.LayoutInflater;
37 import android.view.View;
38 import android.view.View.OnClickListener;
39 import android.view.ViewGroup;
40 import android.view.Window;
41 import android.widget.Button;
42 import android.widget.TextView;
43 
44 import java.util.List;
45 
46 /*
47  * This activity presents UI to uninstall an application. Usually launched with intent
48  * Intent.ACTION_UNINSTALL_PKG_COMMAND and attribute
49  * com.android.packageinstaller.PackageName set to the application package name
50  */
51 public class UninstallerActivity extends Activity implements OnClickListener,
52         DialogInterface.OnCancelListener {
53     private static final String TAG = "UninstallerActivity";
54     private boolean localLOGV = false;
55     PackageManager mPm;
56     private ApplicationInfo mAppInfo;
57     private boolean mAllUsers;
58     private Button mOk;
59     private Button mCancel;
60 
61     // Dialog identifiers used in showDialog
62     private static final int DLG_BASE = 0;
63     private static final int DLG_APP_NOT_FOUND = DLG_BASE + 1;
64     private static final int DLG_UNINSTALL_FAILED = DLG_BASE + 2;
65 
66     @Override
onCreateDialog(int id)67     public Dialog onCreateDialog(int id) {
68         switch (id) {
69         case DLG_APP_NOT_FOUND :
70             return new AlertDialog.Builder(this)
71                     .setTitle(R.string.app_not_found_dlg_title)
72                     .setIcon(com.android.internal.R.drawable.ic_dialog_alert)
73                     .setMessage(R.string.app_not_found_dlg_text)
74                     .setNeutralButton(getString(R.string.dlg_ok),
75                             new DialogInterface.OnClickListener() {
76                                 public void onClick(DialogInterface dialog, int which) {
77                                     setResult(Activity.RESULT_FIRST_USER);
78                                     finish();
79                                 }})
80                     .create();
81         case DLG_UNINSTALL_FAILED :
82             // Guaranteed not to be null. will default to package name if not set by app
83            CharSequence appTitle = mPm.getApplicationLabel(mAppInfo);
84            String dlgText = getString(R.string.uninstall_failed_msg,
85                     appTitle.toString());
86             // Display uninstall failed dialog
87             return new AlertDialog.Builder(this)
88                     .setTitle(R.string.uninstall_failed)
89                     .setIcon(com.android.internal.R.drawable.ic_dialog_alert)
90                     .setMessage(dlgText)
91                     .setNeutralButton(getString(R.string.dlg_ok),
92                             new DialogInterface.OnClickListener() {
93                                 public void onClick(DialogInterface dialog, int which) {
94                                     setResult(Activity.RESULT_FIRST_USER);
95                                     finish();
96                                 }})
97                     .create();
98         }
99         return null;
100     }
101 
102     private void startUninstallProgress() {
103         Intent newIntent = new Intent(Intent.ACTION_VIEW);
104         newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
105                                                   mAppInfo);
106         newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mAllUsers);
107         if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
108             newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
109             newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
110         }
111         newIntent.setClass(this, UninstallAppProgress.class);
112         startActivity(newIntent);
113         finish();
114     }
115 
116     @Override
117     public void onCreate(Bundle icicle) {
118         super.onCreate(icicle);
119         // Get intent information.
120         // We expect an intent with URI of the form package://<packageName>#<className>
121         // className is optional; if specified, it is the activity the user chose to uninstall
122         final Intent intent = getIntent();
123         Uri packageURI = intent.getData();
124         String packageName = packageURI.getEncodedSchemeSpecificPart();
125         if(packageName == null) {
126             Log.e(TAG, "Invalid package name:" + packageName);
127             showDialog(DLG_APP_NOT_FOUND);
128             return;
129         }
130 
131         mPm = getPackageManager();
132         boolean errFlag = false;
133         try {
134             mAppInfo = mPm.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
135         } catch (NameNotFoundException e) {
136             errFlag = true;
137         }
138 
139         mAllUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
140 
141         // The class name may have been specified (e.g. when deleting an app from all apps)
142         String className = packageURI.getFragment();
143         ActivityInfo activityInfo = null;
144         if (className != null) {
145             try {
146                 activityInfo = mPm.getActivityInfo(new ComponentName(packageName, className), 0);
147             } catch (NameNotFoundException e) {
148                 errFlag = true;
149             }
150         }
151 
152         if(mAppInfo == null || errFlag) {
153             Log.e(TAG, "Invalid packageName or componentName in " + packageURI.toString());
154             showDialog(DLG_APP_NOT_FOUND);
155         } else {
156             boolean isUpdate = ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
157 
158             setContentView(R.layout.uninstall_confirm);
159 
160             TextView confirm = (TextView) findViewById(R.id.uninstall_confirm);
161             if (isUpdate) {
162                 setTitle(R.string.uninstall_update_title);
163                 confirm.setText(R.string.uninstall_update_text);
164             } else {
165                 setTitle(R.string.uninstall_application_title);
166                 if (mAllUsers && ((UserManager)getSystemService(
167                         Context.USER_SERVICE)).getUsers().size() >= 2) {
168                     confirm.setText(R.string.uninstall_application_text_all_users);
169                 } else {
170                     confirm.setText(R.string.uninstall_application_text);
171                 }
172             }
173 
174             // If an activity was specified (e.g. when dragging from All Apps to trash can),
175             // give a bit more info if the activity label isn't the same as the package label.
176             if (activityInfo != null) {
177                 CharSequence activityLabel = activityInfo.loadLabel(mPm);
178                 if (!activityLabel.equals(mAppInfo.loadLabel(mPm))) {
179                     TextView activityText = (TextView) findViewById(R.id.activity_text);
180                     CharSequence text = getString(R.string.uninstall_activity_text, activityLabel);
181                     activityText.setText(text);
182                     activityText.setVisibility(View.VISIBLE);
183                 }
184             }
185 
186             View snippetView = findViewById(R.id.uninstall_activity_snippet);
187             PackageUtil.initSnippetForInstalledApp(this, mAppInfo, snippetView);
188 
189             //initialize ui elements
190             mOk = (Button)findViewById(R.id.ok_button);
191             mCancel = (Button)findViewById(R.id.cancel_button);
192             mOk.setOnClickListener(this);
193             mCancel.setOnClickListener(this);
194         }
195     }
196 
197     public void onClick(View v) {
198         if(v == mOk) {
199             //initiate next screen
200             startUninstallProgress();
201         } else if(v == mCancel) {
202             finish();
203         }
204     }
205 
206     public void onCancel(DialogInterface dialog) {
207         finish();
208     }
209 }
210