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 com.android.packageinstaller.R; 20import android.app.Activity; 21import android.app.AlertDialog; 22import android.app.Dialog; 23import android.content.DialogInterface; 24import android.content.Intent; 25import android.content.pm.ApplicationInfo; 26import android.content.pm.PackageManager; 27import android.net.Uri; 28import android.os.Bundle; 29import android.util.Log; 30import android.view.View; 31import android.view.Window; 32import android.view.View.OnClickListener; 33import android.widget.Button; 34import android.widget.TextView; 35import android.content.pm.PackageManager.NameNotFoundException; 36 37/* 38 * This activity presents UI to uninstall an application. Usually launched with intent 39 * Intent.ACTION_UNINSTALL_PKG_COMMAND and attribute 40 * com.android.packageinstaller.PackageName set to the application package name 41 */ 42public class UninstallerActivity extends Activity implements OnClickListener, 43 DialogInterface.OnCancelListener { 44 private static final String TAG = "UninstallerActivity"; 45 private boolean localLOGV = false; 46 PackageManager mPm; 47 private ApplicationInfo mAppInfo; 48 private Button mOk; 49 private Button mCancel; 50 51 // Dialog identifiers used in showDialog 52 private static final int DLG_BASE = 0; 53 private static final int DLG_APP_NOT_FOUND = DLG_BASE + 1; 54 private static final int DLG_UNINSTALL_FAILED = DLG_BASE + 2; 55 56 @Override 57 public Dialog onCreateDialog(int id) { 58 switch (id) { 59 case DLG_APP_NOT_FOUND : 60 return new AlertDialog.Builder(this) 61 .setTitle(R.string.app_not_found_dlg_title) 62 .setIcon(com.android.internal.R.drawable.ic_dialog_alert) 63 .setMessage(R.string.app_not_found_dlg_text) 64 .setNeutralButton(getString(R.string.dlg_ok), 65 new DialogInterface.OnClickListener() { 66 public void onClick(DialogInterface dialog, int which) { 67 finish(); 68 }}) 69 .create(); 70 case DLG_UNINSTALL_FAILED : 71 // Guaranteed not to be null. will default to package name if not set by app 72 CharSequence appTitle = mPm.getApplicationLabel(mAppInfo); 73 String dlgText = getString(R.string.uninstall_failed_msg, 74 appTitle.toString()); 75 // Display uninstall failed dialog 76 return new AlertDialog.Builder(this) 77 .setTitle(R.string.uninstall_failed) 78 .setIcon(com.android.internal.R.drawable.ic_dialog_alert) 79 .setMessage(dlgText) 80 .setNeutralButton(getString(R.string.dlg_ok), 81 new DialogInterface.OnClickListener() { 82 public void onClick(DialogInterface dialog, int which) { 83 finish(); 84 }}) 85 .create(); 86 } 87 return null; 88 } 89 90 private void startUninstallProgress() { 91 Intent newIntent = new Intent(Intent.ACTION_VIEW); 92 newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, 93 mAppInfo); 94 newIntent.setClass(this, UninstallAppProgress.class); 95 startActivity(newIntent); 96 finish(); 97 } 98 99 @Override 100 public void onCreate(Bundle icicle) { 101 super.onCreate(icicle); 102 //get intent information 103 final Intent intent = getIntent(); 104 Uri packageURI = intent.getData(); 105 String packageName = packageURI.getEncodedSchemeSpecificPart(); 106 if(packageName == null) { 107 Log.e(TAG, "Invalid package name:"+packageName); 108 showDialog(DLG_APP_NOT_FOUND); 109 return; 110 } 111 //initialize package manager 112 mPm = getPackageManager(); 113 boolean errFlag = false; 114 try { 115 mAppInfo = mPm.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES); 116 } catch (NameNotFoundException e) { 117 errFlag = true; 118 } 119 if(mAppInfo == null || errFlag) { 120 Log.e(TAG, "Invalid application:"+packageName); 121 showDialog(DLG_APP_NOT_FOUND); 122 } else { 123 requestWindowFeature(Window.FEATURE_NO_TITLE); 124 //set view 125 setContentView(R.layout.uninstall_confirm); 126 TextView question = (TextView) findViewById(R.id.uninstall_question); 127 TextView confirm = (TextView) findViewById(R.id.uninstall_confirm_text); 128 if ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { 129 question.setText(R.string.uninstall_update_question); 130 confirm.setText(R.string.uninstall_update_text); 131 } else { 132 question.setText(R.string.uninstall_application_question); 133 confirm.setText(R.string.uninstall_application_text); 134 } 135 PackageUtil.initSnippetForInstalledApp(this, mAppInfo, R.id.app_snippet); 136 //initialize ui elements 137 mOk = (Button)findViewById(R.id.ok_button); 138 mCancel = (Button)findViewById(R.id.cancel_button); 139 mOk.setOnClickListener(this); 140 mCancel.setOnClickListener(this); 141 } 142 } 143 144 public void onClick(View v) { 145 if(v == mOk) { 146 //initiate next screen 147 startUninstallProgress(); 148 } else if(v == mCancel) { 149 finish(); 150 } 151 } 152 153 public void onCancel(DialogInterface dialog) { 154 finish(); 155 } 156} 157