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.content.Context; 21 import android.content.Intent; 22 import android.content.pm.ApplicationInfo; 23 import android.content.pm.IPackageDeleteObserver; 24 import android.content.pm.PackageManager; 25 import android.os.Bundle; 26 import android.os.Handler; 27 import android.os.Message; 28 import android.util.Log; 29 import android.view.KeyEvent; 30 import android.view.View; 31 import android.view.View.OnClickListener; 32 import android.widget.Button; 33 import android.widget.ProgressBar; 34 import android.widget.TextView; 35 import android.widget.Toast; 36 37 /** 38 * This activity corresponds to a download progress screen that is displayed 39 * when an application is uninstalled. The result of the application uninstall 40 * is indicated in the result code that gets set to 0 or 1. The application gets launched 41 * by an intent with the intent's class name explicitly set to UninstallAppProgress and expects 42 * the application object of the application to uninstall. 43 */ 44 public class UninstallAppProgress extends Activity implements OnClickListener { 45 private final String TAG="UninstallAppProgress"; 46 private boolean localLOGV = false; 47 private ApplicationInfo mAppInfo; 48 private boolean mAllUsers; 49 private TextView mStatusTextView; 50 private Button mOkButton; 51 private Button mDeviceManagerButton; 52 private ProgressBar mProgressBar; 53 private View mOkPanel; 54 private volatile int mResultCode = -1; 55 private final int UNINSTALL_COMPLETE = 1; 56 public final static int SUCCEEDED=1; 57 public final static int FAILED=0; 58 private Handler mHandler = new Handler() { 59 public void handleMessage(Message msg) { 60 switch (msg.what) { 61 case UNINSTALL_COMPLETE: 62 if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { 63 Intent result = new Intent(); 64 result.putExtra(Intent.EXTRA_INSTALL_RESULT, msg.arg1); 65 setResult(msg.arg1 == PackageManager.DELETE_SUCCEEDED 66 ? Activity.RESULT_OK : Activity.RESULT_FIRST_USER, 67 result); 68 finish(); 69 return; 70 } 71 72 mResultCode = msg.arg1; 73 final String packageName = (String) msg.obj; 74 75 // Update the status text 76 final int statusText; 77 switch (msg.arg1) { 78 case PackageManager.DELETE_SUCCEEDED: 79 statusText = R.string.uninstall_done; 80 // Show a Toast and finish the activity 81 Context ctx = getBaseContext(); 82 Toast.makeText(ctx, statusText, Toast.LENGTH_LONG).show(); 83 setResultAndFinish(mResultCode); 84 return; 85 case PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER: 86 Log.d(TAG, "Uninstall failed because " + packageName 87 + " is a device admin"); 88 mDeviceManagerButton.setVisibility(View.VISIBLE); 89 statusText = R.string.uninstall_failed_device_policy_manager; 90 break; 91 default: 92 Log.d(TAG, "Uninstall failed for " + packageName + " with code " 93 + msg.arg1); 94 statusText = R.string.uninstall_failed; 95 break; 96 } 97 mStatusTextView.setText(statusText); 98 99 // Hide the progress bar; Show the ok button 100 mProgressBar.setVisibility(View.INVISIBLE); 101 mOkPanel.setVisibility(View.VISIBLE); 102 break; 103 default: 104 break; 105 } 106 } 107 }; 108 109 @Override 110 public void onCreate(Bundle icicle) { 111 super.onCreate(icicle); 112 Intent intent = getIntent(); 113 mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); 114 mAllUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); 115 initView(); 116 } 117 118 class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 119 public void packageDeleted(String packageName, int returnCode) { 120 Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE); 121 msg.arg1 = returnCode; 122 msg.obj = packageName; 123 mHandler.sendMessage(msg); 124 } 125 } 126 127 void setResultAndFinish(int retCode) { 128 setResult(retCode); 129 finish(); 130 } 131 132 public void initView() { 133 boolean isUpdate = ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0); 134 setTitle(isUpdate ? R.string.uninstall_update_title : R.string.uninstall_application_title); 135 136 setContentView(R.layout.uninstall_progress); 137 // Initialize views 138 View snippetView = findViewById(R.id.app_snippet); 139 PackageUtil.initSnippetForInstalledApp(this, mAppInfo, snippetView); 140 mStatusTextView = (TextView) findViewById(R.id.center_text); 141 mStatusTextView.setText(R.string.uninstalling); 142 mDeviceManagerButton = (Button) findViewById(R.id.device_manager_button); 143 mDeviceManagerButton.setVisibility(View.GONE); 144 mDeviceManagerButton.setOnClickListener(new OnClickListener() { 145 @Override 146 public void onClick(View v) { 147 Intent intent = new Intent(); 148 intent.setClassName("com.android.settings", 149 "com.android.settings.Settings$DeviceAdminSettingsActivity"); 150 intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK); 151 startActivity(intent); 152 finish(); 153 } 154 }); 155 mProgressBar = (ProgressBar) findViewById(R.id.progress_bar); 156 mProgressBar.setIndeterminate(true); 157 // Hide button till progress is being displayed 158 mOkPanel = (View) findViewById(R.id.ok_panel); 159 mOkButton = (Button) findViewById(R.id.ok_button); 160 mOkButton.setOnClickListener(this); 161 mOkPanel.setVisibility(View.INVISIBLE); 162 PackageDeleteObserver observer = new PackageDeleteObserver(); 163 getPackageManager().deletePackage(mAppInfo.packageName, observer, 164 mAllUsers ? PackageManager.DELETE_ALL_USERS : 0); 165 } 166 167 public void onClick(View v) { 168 if(v == mOkButton) { 169 Log.i(TAG, "Finished uninstalling pkg: " + mAppInfo.packageName); 170 setResultAndFinish(mResultCode); 171 } 172 } 173 174 @Override 175 public boolean dispatchKeyEvent(KeyEvent ev) { 176 if (ev.getKeyCode() == KeyEvent.KEYCODE_BACK) { 177 if (mResultCode == -1) { 178 // Ignore back key when installation is in progress 179 return true; 180 } else { 181 // If installation is done, just set the result code 182 setResult(mResultCode); 183 } 184 } 185 return super.dispatchKeyEvent(ev); 186 } 187 } 188