UninstallerActivity.java revision 596ce64f71011e7600ee2be66d977dafb86b9da3
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*/ 17package com.android.packageinstaller; 18 19import android.app.Activity; 20import android.app.AlertDialog; 21import android.app.Dialog; 22import android.content.ComponentName; 23import android.content.Context; 24import android.content.DialogInterface; 25import android.content.Intent; 26import android.content.pm.ActivityInfo; 27import android.content.pm.ApplicationInfo; 28import android.content.pm.IPackageManager; 29import android.content.pm.PackageManager; 30import android.net.Uri; 31import android.os.Bundle; 32import android.os.RemoteException; 33import android.os.ServiceManager; 34import android.os.UserHandle; 35import android.os.UserManager; 36import android.util.Log; 37import android.view.View; 38import android.view.View.OnClickListener; 39import android.widget.Button; 40import android.widget.TextView; 41 42/* 43 * This activity presents UI to uninstall an application. Usually launched with intent 44 * Intent.ACTION_UNINSTALL_PKG_COMMAND and attribute 45 * com.android.packageinstaller.PackageName set to the application package name 46 */ 47public class UninstallerActivity extends Activity implements OnClickListener, 48 DialogInterface.OnCancelListener { 49 private static final String TAG = "UninstallerActivity"; 50 private boolean localLOGV = false; 51 PackageManager mPm; 52 private IPackageManager mIpm; 53 private ApplicationInfo mAppInfo; 54 private boolean mAllUsers; 55 private Button mOk; 56 private Button mCancel; 57 private UserHandle mUserHandle; 58 59 // Dialog identifiers used in showDialog 60 private static final int DLG_BASE = 0; 61 private static final int DLG_APP_NOT_FOUND = DLG_BASE + 1; 62 private static final int DLG_UNINSTALL_FAILED = DLG_BASE + 2; 63 64 @Override 65 public Dialog onCreateDialog(int id) { 66 switch (id) { 67 case DLG_APP_NOT_FOUND : 68 return new AlertDialog.Builder(this) 69 .setTitle(R.string.app_not_found_dlg_title) 70 .setIcon(com.android.internal.R.drawable.ic_dialog_alert) 71 .setMessage(R.string.app_not_found_dlg_text) 72 .setNeutralButton(getString(R.string.dlg_ok), 73 new DialogInterface.OnClickListener() { 74 public void onClick(DialogInterface dialog, int which) { 75 setResult(Activity.RESULT_FIRST_USER); 76 finish(); 77 }}) 78 .create(); 79 case DLG_UNINSTALL_FAILED : 80 // Guaranteed not to be null. will default to package name if not set by app 81 CharSequence appTitle = mPm.getApplicationLabel(mAppInfo); 82 String dlgText = getString(R.string.uninstall_failed_msg, 83 appTitle.toString()); 84 // Display uninstall failed dialog 85 return new AlertDialog.Builder(this) 86 .setTitle(R.string.uninstall_failed) 87 .setIcon(com.android.internal.R.drawable.ic_dialog_alert) 88 .setMessage(dlgText) 89 .setNeutralButton(getString(R.string.dlg_ok), 90 new DialogInterface.OnClickListener() { 91 public void onClick(DialogInterface dialog, int which) { 92 setResult(Activity.RESULT_FIRST_USER); 93 finish(); 94 }}) 95 .create(); 96 } 97 return null; 98 } 99 100 private void startUninstallProgress() { 101 Intent newIntent = new Intent(Intent.ACTION_VIEW); 102 newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, 103 mAppInfo); 104 newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mAllUsers); 105 newIntent.putExtra(Intent.EXTRA_USER, mUserHandle); 106 if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { 107 newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true); 108 newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); 109 } 110 newIntent.setClass(this, UninstallAppProgress.class); 111 startActivity(newIntent); 112 finish(); 113 } 114 115 @Override 116 public void onCreate(Bundle icicle) { 117 super.onCreate(icicle); 118 // Get intent information. 119 // We expect an intent with URI of the form package://<packageName>#<className> 120 // className is optional; if specified, it is the activity the user chose to uninstall 121 final Intent intent = getIntent(); 122 Uri packageURI = intent.getData(); 123 String packageName = packageURI.getEncodedSchemeSpecificPart(); 124 if(packageName == null) { 125 Log.e(TAG, "Invalid package name:" + packageName); 126 showDialog(DLG_APP_NOT_FOUND); 127 return; 128 } 129 130 mUserHandle = intent.getParcelableExtra(Intent.EXTRA_USER); 131 if (mUserHandle == null) { 132 mUserHandle = android.os.Process.myUserHandle(); 133 } 134 135 mPm = getPackageManager(); 136 mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 137 138 boolean errFlag = false; 139 try { 140 mAppInfo = mIpm.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES, 141 mUserHandle.getIdentifier()); 142 } catch (RemoteException e) { 143 errFlag = true; 144 } 145 146 mAllUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); 147 148 // The class name may have been specified (e.g. when deleting an app from all apps) 149 String className = packageURI.getFragment(); 150 ActivityInfo activityInfo = null; 151 if (className != null) { 152 try { 153 activityInfo = mIpm.getActivityInfo(new ComponentName(packageName, className), 0, 154 mUserHandle.getIdentifier()); 155 } catch (RemoteException e) { 156 errFlag = true; 157 } 158 } 159 160 if(mAppInfo == null || errFlag) { 161 Log.e(TAG, "Invalid packageName or componentName in " + packageURI.toString()); 162 showDialog(DLG_APP_NOT_FOUND); 163 } else { 164 boolean isUpdate = ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0); 165 166 setContentView(R.layout.uninstall_confirm); 167 168 TextView confirm = (TextView) findViewById(R.id.uninstall_confirm); 169 if (isUpdate) { 170 setTitle(R.string.uninstall_update_title); 171 confirm.setText(R.string.uninstall_update_text); 172 } else { 173 UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); 174 setTitle(R.string.uninstall_application_title); 175 if (mAllUsers && userManager.getUsers().size() >= 2) { 176 confirm.setText(R.string.uninstall_application_text_all_users); 177 } else if (!mUserHandle.equals(android.os.Process.myUserHandle())) { 178 String userName = userManager.getUserInfo(mUserHandle.getIdentifier()).name; 179 confirm.setText(String.format( 180 getString(R.string.uninstall_application_text_user), userName)); 181 } else { 182 confirm.setText(R.string.uninstall_application_text); 183 } 184 } 185 186 // If an activity was specified (e.g. when dragging from All Apps to trash can), 187 // give a bit more info if the activity label isn't the same as the package label. 188 if (activityInfo != null) { 189 CharSequence activityLabel = activityInfo.loadLabel(mPm); 190 if (!activityLabel.equals(mAppInfo.loadLabel(mPm))) { 191 TextView activityText = (TextView) findViewById(R.id.activity_text); 192 CharSequence text = getString(R.string.uninstall_activity_text, activityLabel); 193 activityText.setText(text); 194 activityText.setVisibility(View.VISIBLE); 195 } 196 } 197 198 View snippetView = findViewById(R.id.uninstall_activity_snippet); 199 PackageUtil.initSnippetForInstalledApp(this, mAppInfo, snippetView, mUserHandle); 200 201 //initialize ui elements 202 mOk = (Button)findViewById(R.id.ok_button); 203 mCancel = (Button)findViewById(R.id.cancel_button); 204 mOk.setOnClickListener(this); 205 mCancel.setOnClickListener(this); 206 } 207 } 208 209 public void onClick(View v) { 210 if(v == mOk) { 211 //initiate next screen 212 startUninstallProgress(); 213 } else if(v == mCancel) { 214 finish(); 215 } 216 } 217 218 public void onCancel(DialogInterface dialog) { 219 finish(); 220 } 221} 222