summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2014-08-29 11:30:47 -0700
committerAdam Lesinski <adamlesinski@google.com>2014-09-10 12:28:35 -0700
commit3e3e1126d588bb1fb1879c34a0f9963206ec8f22 (patch)
tree4ca5bf08fec99db207fca7335ae5c5b02d34ad92
parentdee544d68c92a3e1f66a981b8e232941c9b582a4 (diff)
downloadandroid_packages_apps_PackageInstaller-3e3e1126d588bb1fb1879c34a0f9963206ec8f22.tar.gz
android_packages_apps_PackageInstaller-3e3e1126d588bb1fb1879c34a0f9963206ec8f22.tar.bz2
android_packages_apps_PackageInstaller-3e3e1126d588bb1fb1879c34a0f9963206ec8f22.zip
Use an AlertDialog for the Uninstall confirmation
This allows us to get the correct theming for free moving forward. Bug:17045520 Change-Id: I173315b39816b0061c048459e1f14d81747f072b
-rw-r--r--AndroidManifest.xml4
-rwxr-xr-xres/values-large/styles.xml21
-rwxr-xr-xres/values/styles.xml4
-rwxr-xr-xsrc/com/android/packageinstaller/UninstallerActivity.java278
4 files changed, 156 insertions, 151 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 66d22542..ca8777d0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -17,7 +17,7 @@
<application android:label="@string/app_name"
android:allowBackup="false"
- android:theme="@android:style/Theme.DeviceDefault.DialogWhenLarge.NoActionBar"
+ android:theme="@style/Theme.DialogWhenLarge"
android:supportsRtl="true">
<activity android:name=".PackageInstallerActivity"
@@ -49,7 +49,7 @@
<activity android:name=".UninstallerActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="true"
- android:theme="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
+ android:theme="@style/Theme.AlertDialogActivity">
<intent-filter>
<action android:name="android.intent.action.DELETE" />
<action android:name="android.intent.action.UNINSTALL_PACKAGE" />
diff --git a/res/values-large/styles.xml b/res/values-large/styles.xml
deleted file mode 100755
index c7b2ec42..00000000
--- a/res/values-large/styles.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="DialogWhenLarge"
- parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar.MinWidth">
- </style>
-</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f935675f..b5d8d480 100755
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -19,6 +19,8 @@
<item name="android:paddingStart">16dip</item>
<item name="android:paddingEnd">16dip</item>
</style>
- <style name="DialogWhenLarge" parent="@android:style/Theme.DeviceDefault.NoActionBar">
+ <style name="Theme.DialogWhenLarge" parent="@android:style/Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar"/>
+ <style name="Theme.AlertDialogActivity" parent="@android:style/Theme.DeviceDefault.Light.Panel">
+ <item name="android:backgroundDimEnabled">true</item>
</style>
</resources>
diff --git a/src/com/android/packageinstaller/UninstallerActivity.java b/src/com/android/packageinstaller/UninstallerActivity.java
index 531754e2..96bc9937 100755
--- a/src/com/android/packageinstaller/UninstallerActivity.java
+++ b/src/com/android/packageinstaller/UninstallerActivity.java
@@ -19,8 +19,10 @@ package com.android.packageinstaller;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
import android.content.ComponentName;
-import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -29,6 +31,7 @@ import android.content.pm.IPackageDeleteObserver2;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -37,70 +40,109 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.TextView;
/*
* This activity presents UI to uninstall an application. Usually launched with intent
* Intent.ACTION_UNINSTALL_PKG_COMMAND and attribute
* com.android.packageinstaller.PackageName set to the application package name
*/
-public class UninstallerActivity extends Activity implements OnClickListener {
+public class UninstallerActivity extends Activity {
private static final String TAG = "UninstallerActivity";
- private boolean localLOGV = false;
- private PackageManager mPm;
- private IPackageManager mIpm;
+ public static class UninstallAlertDialogFragment extends DialogFragment implements
+ DialogInterface.OnClickListener {
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final PackageManager pm = getActivity().getPackageManager();
+ final DialogInfo dialogInfo = ((UninstallerActivity) getActivity()).mDialogInfo;
+ final CharSequence appLabel = dialogInfo.appInfo.loadLabel(pm);
+
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
+ StringBuilder messageBuilder = new StringBuilder();
+
+ // If the Activity label differs from the App label, then make sure the user
+ // knows the Activity belongs to the App being uninstalled.
+ if (dialogInfo.activityInfo != null) {
+ final CharSequence activityLabel = dialogInfo.activityInfo.loadLabel(pm);
+ if (!activityLabel.equals(appLabel)) {
+ messageBuilder.append(
+ getString(R.string.uninstall_activity_text, activityLabel));
+ messageBuilder.append(" ").append(appLabel).append(".\n\n");
+ }
+ }
- private UserHandle mUserHandle;
- private ApplicationInfo mAppInfo;
- private boolean mAllUsers;
- private IBinder mCallback;
+ final boolean isUpdate =
+ ((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+ if (isUpdate) {
+ messageBuilder.append(getString(R.string.uninstall_update_text));
+ } else {
+ UserManager userManager = UserManager.get(getActivity());
+ if (dialogInfo.allUsers && userManager.getUserCount() >= 2) {
+ messageBuilder.append(getString(R.string.uninstall_application_text_all_users));
+ } else if (!dialogInfo.user.equals(android.os.Process.myUserHandle())) {
+ UserInfo userInfo = userManager.getUserInfo(dialogInfo.user.getIdentifier());
+ messageBuilder.append(
+ getString(R.string.uninstall_application_text_user, userInfo.name));
+ } else {
+ messageBuilder.append(getString(R.string.uninstall_application_text));
+ }
+ }
- private Button mOk;
- private Button mCancel;
+ dialogBuilder.setTitle(appLabel);
+ dialogBuilder.setIcon(dialogInfo.appInfo.loadIcon(pm));
+ dialogBuilder.setPositiveButton(android.R.string.ok, this);
+ dialogBuilder.setNegativeButton(android.R.string.cancel, this);
+ dialogBuilder.setMessage(messageBuilder.toString());
+ return dialogBuilder.create();
+ }
- // Dialog identifiers used in showDialog
- private static final int DLG_BASE = 0;
- private static final int DLG_APP_NOT_FOUND = DLG_BASE + 1;
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == Dialog.BUTTON_POSITIVE) {
+ ((UninstallerActivity) getActivity()).startUninstallProgress();
+ } else {
+ ((UninstallerActivity) getActivity()).dispatchAborted();
+ }
+ }
- @Override
- public Dialog onCreateDialog(int id) {
- switch (id) {
- case DLG_APP_NOT_FOUND :
- return new AlertDialog.Builder(this)
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ getActivity().finish();
+ }
+ }
+
+ public static class AppNotFoundDialogFragment extends DialogFragment {
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
.setTitle(R.string.app_not_found_dlg_title)
- .setIcon(com.android.internal.R.drawable.ic_dialog_alert)
.setMessage(R.string.app_not_found_dlg_text)
- .setNeutralButton(getString(R.string.dlg_ok),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dispatchAborted();
- setResult(Activity.RESULT_FIRST_USER);
- finish();
- }})
+ .setNeutralButton(android.R.string.ok, null)
.create();
}
- return null;
- }
- private void startUninstallProgress() {
- Intent newIntent = new Intent(Intent.ACTION_VIEW);
- newIntent.putExtra(Intent.EXTRA_USER, mUserHandle);
- newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mAllUsers);
- newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mCallback);
- newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mAppInfo);
- if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
- newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
- newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ ((UninstallerActivity) getActivity()).dispatchAborted();
+ getActivity().setResult(Activity.RESULT_FIRST_USER);
+ getActivity().finish();
}
- newIntent.setClass(this, UninstallAppProgress.class);
- startActivity(newIntent);
- finish();
}
+ static class DialogInfo {
+ ApplicationInfo appInfo;
+ ActivityInfo activityInfo;
+ boolean allUsers;
+ UserHandle user;
+ IBinder callback;
+ }
+
+ private DialogInfo mDialogInfo;
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -108,116 +150,98 @@ public class UninstallerActivity extends Activity implements OnClickListener {
// We expect an intent with URI of the form package://<packageName>#<className>
// className is optional; if specified, it is the activity the user chose to uninstall
final Intent intent = getIntent();
- Uri packageURI = intent.getData();
- String packageName = packageURI.getEncodedSchemeSpecificPart();
- if(packageName == null) {
- Log.e(TAG, "Invalid package name:" + packageName);
- showDialog(DLG_APP_NOT_FOUND);
+ final Uri packageUri = intent.getData();
+ if (packageUri == null) {
+ Log.e(TAG, "No package URI in intent");
+ showAppNotFound();
+ return;
+ }
+ final String packageName = packageUri.getEncodedSchemeSpecificPart();
+ if (packageName == null) {
+ Log.e(TAG, "Invalid package name in URI: " + packageUri);
+ showAppNotFound();
return;
}
- mPm = getPackageManager();
- mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+ final IPackageManager pm = IPackageManager.Stub.asInterface(
+ ServiceManager.getService("package"));
- mUserHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
- if (mUserHandle == null) {
- mUserHandle = android.os.Process.myUserHandle();
+ mDialogInfo = new DialogInfo();
+
+ mDialogInfo.user = intent.getParcelableExtra(Intent.EXTRA_USER);
+ if (mDialogInfo.user == null) {
+ mDialogInfo.user = android.os.Process.myUserHandle();
}
- mAllUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
- mCallback = intent.getIBinderExtra(PackageInstaller.EXTRA_CALLBACK);
- boolean errFlag = false;
+ mDialogInfo.allUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
+ mDialogInfo.callback = intent.getIBinderExtra(PackageInstaller.EXTRA_CALLBACK);
+
try {
- mAppInfo = mIpm.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES,
- mUserHandle.getIdentifier());
+ mDialogInfo.appInfo = pm.getApplicationInfo(packageName,
+ PackageManager.GET_UNINSTALLED_PACKAGES, mDialogInfo.user.getIdentifier());
} catch (RemoteException e) {
- errFlag = true;
+ Log.e(TAG, "Unable to get packageName. Package manager is dead?");
+ }
+
+ if (mDialogInfo.appInfo == null) {
+ Log.e(TAG, "Invalid packageName: " + packageName);
+ showAppNotFound();
+ return;
}
// The class name may have been specified (e.g. when deleting an app from all apps)
- String className = packageURI.getFragment();
- ActivityInfo activityInfo = null;
+ final String className = packageUri.getFragment();
if (className != null) {
try {
- activityInfo = mIpm.getActivityInfo(new ComponentName(packageName, className), 0,
- mUserHandle.getIdentifier());
+ mDialogInfo.activityInfo = pm.getActivityInfo(
+ new ComponentName(packageName, className), 0,
+ mDialogInfo.user.getIdentifier());
} catch (RemoteException e) {
- errFlag = true;
+ Log.e(TAG, "Unable to get className. Package manager is dead?");
+ // Continue as the ActivityInfo isn't critical.
}
}
- if(mAppInfo == null || errFlag) {
- Log.e(TAG, "Invalid packageName or componentName in " + packageURI.toString());
- showDialog(DLG_APP_NOT_FOUND);
- } else {
- boolean isUpdate = ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
-
- setContentView(R.layout.uninstall_confirm);
-
- TextView confirm = (TextView) findViewById(R.id.uninstall_confirm);
- if (isUpdate) {
- setTitle(R.string.uninstall_update_title);
- confirm.setText(R.string.uninstall_update_text);
- } else {
- UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
- setTitle(R.string.uninstall_application_title);
- if (mAllUsers && userManager.getUsers().size() >= 2) {
- confirm.setText(R.string.uninstall_application_text_all_users);
- } else if (!mUserHandle.equals(android.os.Process.myUserHandle())) {
- String userName = userManager.getUserInfo(mUserHandle.getIdentifier()).name;
- confirm.setText(String.format(
- getString(R.string.uninstall_application_text_user), userName));
- } else {
- confirm.setText(R.string.uninstall_application_text);
- }
- }
-
- // If an activity was specified (e.g. when dragging from All Apps to trash can),
- // give a bit more info if the activity label isn't the same as the package label.
- if (activityInfo != null) {
- CharSequence activityLabel = activityInfo.loadLabel(mPm);
- if (!activityLabel.equals(mAppInfo.loadLabel(mPm))) {
- TextView activityText = (TextView) findViewById(R.id.activity_text);
- CharSequence text = getString(R.string.uninstall_activity_text, activityLabel);
- activityText.setText(text);
- activityText.setVisibility(View.VISIBLE);
- }
- }
+ showConfirmationDialog();
+ }
- View snippetView = findViewById(R.id.uninstall_activity_snippet);
- PackageUtil.initSnippetForInstalledApp(this, mAppInfo, snippetView, mUserHandle);
+ private void showConfirmationDialog() {
+ showDialogFragment(new UninstallAlertDialogFragment());
+ }
- //initialize ui elements
- mOk = (Button)findViewById(R.id.ok_button);
- mCancel = (Button)findViewById(R.id.cancel_button);
- mOk.setOnClickListener(this);
- mCancel.setOnClickListener(this);
- }
+ private void showAppNotFound() {
+ showDialogFragment(new AppNotFoundDialogFragment());
}
- @Override
- public void onBackPressed() {
- dispatchAborted();
- super.onBackPressed();
+ private void showDialogFragment(DialogFragment fragment) {
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ Fragment prev = getFragmentManager().findFragmentByTag("dialog");
+ if (prev != null) {
+ ft.remove(prev);
+ }
+ fragment.show(ft, "dialog");
}
- @Override
- public void onClick(View v) {
- if(v == mOk) {
- //initiate next screen
- startUninstallProgress();
- } else if (v == mCancel) {
- dispatchAborted();
- finish();
+ void startUninstallProgress() {
+ Intent newIntent = new Intent(Intent.ACTION_VIEW);
+ newIntent.putExtra(Intent.EXTRA_USER, mDialogInfo.user);
+ newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers);
+ newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mDialogInfo.callback);
+ newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo);
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
}
+ newIntent.setClass(this, UninstallAppProgress.class);
+ startActivity(newIntent);
}
- private void dispatchAborted() {
- if (mCallback != null) {
+ void dispatchAborted() {
+ if (mDialogInfo != null && mDialogInfo.callback != null) {
final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub.asInterface(
- mCallback);
+ mDialogInfo.callback);
try {
- observer.onPackageDeleted(mAppInfo.packageName,
+ observer.onPackageDeleted(mDialogInfo.appInfo.packageName,
PackageManager.DELETE_FAILED_ABORTED, "Cancelled by user");
} catch (RemoteException ignored) {
}