diff options
author | Kenny Root <kroot@google.com> | 2011-02-28 13:38:12 -0800 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2011-03-16 16:58:02 -0700 |
commit | bae45d9ae440e20d1a261e81b6acdf02130a305a (patch) | |
tree | 423fcd43df6b6992752f27429015d7142815a283 | |
parent | ac84e2fe02c861875382b28ba89da2f92d8a65f5 (diff) | |
download | android_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.xml | 21 | ||||
-rwxr-xr-x | res/layout/op_progress.xml | 13 | ||||
-rwxr-xr-x | res/layout/uninstall_progress.xml | 9 | ||||
-rw-r--r-- | res/values/strings.xml | 27 | ||||
-rwxr-xr-x | src/com/android/packageinstaller/InstallAppProgress.java | 37 | ||||
-rwxr-xr-x | src/com/android/packageinstaller/UninstallAppProgress.java | 51 |
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(); |