summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2011-02-28 13:38:12 -0800
committerKenny Root <kroot@google.com>2011-03-16 16:58:02 -0700
commitbae45d9ae440e20d1a261e81b6acdf02130a305a (patch)
tree423fcd43df6b6992752f27429015d7142815a283
parentac84e2fe02c861875382b28ba89da2f92d8a65f5 (diff)
downloadandroid_packages_apps_PackageInstaller-bae45d9ae440e20d1a261e81b6acdf02130a305a.tar.gz
android_packages_apps_PackageInstaller-bae45d9ae440e20d1a261e81b6acdf02130a305a.tar.bz2
android_packages_apps_PackageInstaller-bae45d9ae440e20d1a261e81b6acdf02130a305a.zip
More descriptive errors for install failures
Change-Id: Ica79bece0fd29c27126e1ee51daeac96affaa1ab
-rw-r--r--res/drawable/ic_result_status.xml21
-rwxr-xr-xres/layout/op_progress.xml13
-rwxr-xr-xres/layout/uninstall_progress.xml9
-rw-r--r--res/values/strings.xml27
-rwxr-xr-xsrc/com/android/packageinstaller/InstallAppProgress.java37
-rwxr-xr-xsrc/com/android/packageinstaller/UninstallAppProgress.java51
6 files changed, 142 insertions, 16 deletions
diff --git a/res/drawable/ic_result_status.xml b/res/drawable/ic_result_status.xml
new file mode 100644
index 00000000..5e8fe977
--- /dev/null
+++ b/res/drawable/ic_result_status.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- success state -->
+ <item android:maxLevel="0" android:drawable="@drawable/button_indicator_finish"/>
+ <!-- failure state -->
+ <item android:maxLevel="1" android:drawable="@android:drawable/ic_delete"/>
+</level-list> \ No newline at end of file
diff --git a/res/layout/op_progress.xml b/res/layout/op_progress.xml
index ded050c3..4e8f9b1f 100755
--- a/res/layout/op_progress.xml
+++ b/res/layout/op_progress.xml
@@ -31,8 +31,19 @@
android:text="@string/installing"
android:paddingTop="16dip"
android:paddingLeft="16dip"
- android:paddingBottom="16dip"
android:textAppearance="?android:attr/textAppearanceMedium"/>
+ <TextView
+ android:id="@+id/center_explanation"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:visibility="gone"
+ android:paddingTop="8dip"
+ android:paddingLeft="16dip"
+ android:paddingBottom="16dip"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
+
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
diff --git a/res/layout/uninstall_progress.xml b/res/layout/uninstall_progress.xml
index e9e1ec29..951f2446 100755
--- a/res/layout/uninstall_progress.xml
+++ b/res/layout/uninstall_progress.xml
@@ -32,6 +32,15 @@
style="@style/padded"
android:paddingBottom="16dip"
android:textAppearance="?android:attr/textAppearanceMedium" />
+ <Button android:id="@+id/device_manager_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:layout_gravity="center_horizontal"
+ android:maxLines="2"
+ android:text="@string/manage_device_administrators"/>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5dbae68a..d8749782 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -26,6 +26,25 @@
<string name="install_done">Application installed</string>
<string name="install_confirm_question">Do you want to install this application?</string>
<string name="install_failed">Application not installed</string>
+ <!-- Reason displayed when installation fails because the installation package itself is invalid
+ in some way (e.g., corrupt) [CHAR LIMIT=100] -->
+ <string name="install_failed_invalid_apk">The package appears to be corrupt.</string>
+ <!-- Reason displayed when installation fails because the package an existing package is
+ installed with a conflicting package author signature [CHAR LIMIT=100] -->
+ <string name="install_failed_inconsistent_certificates">An existing package by the same name
+ with a conflicting signature is already installed.</string>
+ <!-- Reason displayed when installation fails because the package specifies a minimum compatible
+ OS version that is newer than our current OS version. [CHAR LIMIT=100] -->
+ <string name="install_failed_older_sdk">The package only works on newer versions of
+ Android.</string>
+ <!-- Reason displayed when installation fails because the package specifies it is compatible
+ only with a CPU that the current tablet doesn't have. [CHAR LIMIT=100] -->
+ <string name="install_failed_cpu_abi_incompatible" product="tablet">This application is not
+ compatible with this tablet\'s CPU.</string>
+ <!-- Reason displayed when installation fails because the package specifies it is compatible
+ only with a CPU that the current phone doesn't have. [CHAR LIMIT=100] -->
+ <string name="install_failed_cpu_abi_incompatible" product="default">This application is not
+ compatible with this phone\'s CPU.</string>
<!-- Message presented when an application could not be installed on the tablet for some reason. [CHAR LIMIT=100] -->
<string name="install_failed_msg" product="tablet"><xliff:g id="app_name">%1$s</xliff:g> could not be installed on this tablet.</string>
<!-- Message presented when an application could not be installed on the phone for some reason. [CHAR LIMIT=100] -->
@@ -58,6 +77,14 @@ found in the list of installed applications.</string>
<string name="uninstalling">Uninstalling\u2026</string>
<string name="uninstall_done">Uninstall finished</string>
<string name="uninstall_failed">Uninstall not successful</string>
+ <!-- String presented to the user when uninstalling a package failed because the target package
+ is a current device administrator [CHAR LIMIT=80] -->
+ <string name="uninstall_failed_device_policy_manager">Cannot uninstall: this package is an
+ active device administrator.</string>
+ <!-- String on a button that leads to the "device administrator" configuration setting where a
+ user will be able to disable the device administrator in order to uninstall
+ it. [CHAR LIMIT=50] -->
+ <string name="manage_device_administrators">Manage device administrators</string>
<string name="uninstall_failed_msg"><xliff:g id="app_name">%1$s</xliff:g> could not be uninstalled</string>
<!-- Dialog attributes to indicate parse errors -->
diff --git a/src/com/android/packageinstaller/InstallAppProgress.java b/src/com/android/packageinstaller/InstallAppProgress.java
index 45d8391b..08a6d1dd 100755
--- a/src/com/android/packageinstaller/InstallAppProgress.java
+++ b/src/com/android/packageinstaller/InstallAppProgress.java
@@ -32,6 +32,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LevelListDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -61,6 +62,7 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
private ProgressBar mProgressBar;
private View mOkPanel;
private TextView mStatusTextView;
+ private TextView mExplanationTextView;
private Button mDoneButton;
private Button mLaunchButton;
private final int INSTALL_COMPLETE = 1;
@@ -76,10 +78,12 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
mProgressBar.setVisibility(View.INVISIBLE);
// Show the ok button
int centerTextLabel;
- Drawable centerTextDrawable = null;
- if(msg.arg1 == PackageManager.INSTALL_SUCCEEDED) {
+ int centerExplanationLabel = -1;
+ LevelListDrawable centerTextDrawable = (LevelListDrawable) getResources()
+ .getDrawable(R.drawable.ic_result_status);
+ if (msg.arg1 == PackageManager.INSTALL_SUCCEEDED) {
mLaunchButton.setVisibility(View.VISIBLE);
- centerTextDrawable = getResources().getDrawable(R.drawable.button_indicator_finish);
+ centerTextDrawable.setLevel(0);
centerTextLabel = R.string.install_done;
// Enable or disable launch button
mLaunchIntent = getPackageManager().getLaunchIntentForPackage(
@@ -102,8 +106,8 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
return;
} else {
// Generic error handling for all other error codes.
- centerTextDrawable = Resources.getSystem().getDrawable(
- com.android.internal.R.drawable.ic_bullet_key_permission);
+ centerTextDrawable.setLevel(1);
+ centerExplanationLabel = getExplanationFromErrorCode(msg.arg1);
centerTextLabel = R.string.install_failed;
mLaunchButton.setVisibility(View.INVISIBLE);
}
@@ -114,6 +118,12 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
mStatusTextView.setCompoundDrawables(centerTextDrawable, null, null, null);
}
mStatusTextView.setText(centerTextLabel);
+ if (centerExplanationLabel != -1) {
+ mExplanationTextView.setText(centerExplanationLabel);
+ mExplanationTextView.setVisibility(View.VISIBLE);
+ } else {
+ mExplanationTextView.setVisibility(View.GONE);
+ }
mDoneButton.setOnClickListener(InstallAppProgress.this);
mOkPanel.setVisibility(View.VISIBLE);
break;
@@ -123,6 +133,22 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
}
};
+ private int getExplanationFromErrorCode(int errCode) {
+ Log.d(TAG, "Installation error code: " + errCode);
+ switch (errCode) {
+ case PackageManager.INSTALL_FAILED_INVALID_APK:
+ return R.string.install_failed_invalid_apk;
+ case PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES:
+ return R.string.install_failed_inconsistent_certificates;
+ case PackageManager.INSTALL_FAILED_OLDER_SDK:
+ return R.string.install_failed_older_sdk;
+ case PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE:
+ return R.string.install_failed_cpu_abi_incompatible;
+ default:
+ return -1;
+ }
+ }
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -194,6 +220,7 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
mStatusTextView = (TextView)findViewById(R.id.center_text);
mStatusTextView.setText(R.string.installing);
+ mExplanationTextView = (TextView) findViewById(R.id.center_explanation);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mProgressBar.setIndeterminate(true);
// Hide button till progress is being displayed
diff --git a/src/com/android/packageinstaller/UninstallAppProgress.java b/src/com/android/packageinstaller/UninstallAppProgress.java
index fd094cfb..b4d71476 100755
--- a/src/com/android/packageinstaller/UninstallAppProgress.java
+++ b/src/com/android/packageinstaller/UninstallAppProgress.java
@@ -45,6 +45,7 @@ public class UninstallAppProgress extends Activity implements OnClickListener {
private ApplicationInfo mAppInfo;
private TextView mStatusTextView;
private Button mOkButton;
+ private Button mDeviceManagerButton;
private ProgressBar mProgressBar;
private View mOkPanel;
private volatile int mResultCode = -1;
@@ -56,14 +57,30 @@ public class UninstallAppProgress extends Activity implements OnClickListener {
switch (msg.what) {
case UNINSTALL_COMPLETE:
mResultCode = msg.arg1;
+ final String packageName = (String) msg.obj;
+
// Update the status text
- if (msg.arg1 == SUCCEEDED) {
- mStatusTextView.setText(R.string.uninstall_done);
- } else {
- mStatusTextView.setText(R.string.uninstall_failed);
+ final int statusText;
+ switch (msg.arg1) {
+ case PackageManager.DELETE_SUCCEEDED:
+ statusText = R.string.uninstall_done;
+ break;
+ case PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER:
+ Log.d(TAG, "Uninstall failed because " + packageName
+ + " is a device admin");
+ mDeviceManagerButton.setVisibility(View.VISIBLE);
+ statusText = R.string.uninstall_failed_device_policy_manager;
+ break;
+ default:
+ Log.d(TAG, "Uninstall failed for " + packageName + " with code "
+ + msg.arg1);
+ statusText = R.string.uninstall_failed;
+ break;
}
+ mStatusTextView.setText(statusText);
+
+ // Hide the progress bar; Show the ok button
mProgressBar.setVisibility(View.INVISIBLE);
- // Show the ok button
mOkPanel.setVisibility(View.VISIBLE);
break;
default:
@@ -71,7 +88,7 @@ public class UninstallAppProgress extends Activity implements OnClickListener {
}
}
};
-
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -83,7 +100,8 @@ public class UninstallAppProgress extends Activity implements OnClickListener {
class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
public void packageDeleted(String packageName, int returnCode) {
Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE);
- msg.arg1 = returnCode == PackageManager.DELETE_SUCCEEDED ? SUCCEEDED : FAILED;
+ msg.arg1 = returnCode;
+ msg.obj = packageName;
mHandler.sendMessage(msg);
}
}
@@ -101,13 +119,26 @@ public class UninstallAppProgress extends Activity implements OnClickListener {
// Initialize views
View snippetView = findViewById(R.id.app_snippet);
PackageUtil.initSnippetForInstalledApp(this, mAppInfo, snippetView);
- mStatusTextView = (TextView)findViewById(R.id.center_text);
+ mStatusTextView = (TextView) findViewById(R.id.center_text);
mStatusTextView.setText(R.string.uninstalling);
+ mDeviceManagerButton = (Button) findViewById(R.id.device_manager_button);
+ mDeviceManagerButton.setVisibility(View.GONE);
+ mDeviceManagerButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$DeviceAdminSettingsActivity");
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ finish();
+ }
+ });
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mProgressBar.setIndeterminate(true);
// Hide button till progress is being displayed
- mOkPanel = (View)findViewById(R.id.ok_panel);
- mOkButton = (Button)findViewById(R.id.ok_button);
+ mOkPanel = (View) findViewById(R.id.ok_panel);
+ mOkButton = (Button) findViewById(R.id.ok_button);
mOkButton.setOnClickListener(this);
mOkPanel.setVisibility(View.INVISIBLE);
PackageDeleteObserver observer = new PackageDeleteObserver();