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