Merge "Fix issue #7330867: Cannot disable a built-in app if you've downloaded updates" into jb-mr1-dev

This commit is contained in:
Dianne Hackborn
2012-10-14 11:07:45 -07:00
committed by Android (Google) Code Review
3 changed files with 105 additions and 31 deletions

View File

@@ -49,6 +49,11 @@
layout="@layout/two_buttons_panel" layout="@layout/two_buttons_panel"
android:id="@+id/control_buttons_panel"/> android:id="@+id/control_buttons_panel"/>
<!-- Force stop and uninstall buttons -->
<include
layout="@layout/two_buttons_panel"
android:id="@+id/more_control_buttons_panel"/>
<!-- Ban notifications for this package --> <!-- Ban notifications for this package -->
<CheckBox android:id="@+id/notification_switch" <CheckBox android:id="@+id/notification_switch"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -2707,6 +2707,11 @@
<!-- [CHAR LIMIT=200] Manage applications, text for dialog when disabling apps --> <!-- [CHAR LIMIT=200] Manage applications, text for dialog when disabling apps -->
<string name="app_disable_dlg_text">If you disable a built-in app, other apps <string name="app_disable_dlg_text">If you disable a built-in app, other apps
may misbehave.</string> may misbehave.</string>
<!-- [CHAR LIMIT=NONE] Manage applications, title for dialog when disabling updated apps -->
<string name="app_special_disable_dlg_title">Delete data and disable app?</string>
<!-- [CHAR LIMIT=NONE] Manage applications, text for dialog when disabling update apps -->
<string name="app_special_disable_dlg_text">If you disable a built-in app, other apps
may misbehave. Your data will also be deleted.</string>
<!-- [CHAR LIMIT=30] Manage applications, title for dialog when disabling notifications for an app --> <!-- [CHAR LIMIT=30] Manage applications, title for dialog when disabling notifications for an app -->
<string name="app_disable_notifications_dlg_title">Turn off notifications?</string> <string name="app_disable_notifications_dlg_title">Turn off notifications?</string>
<!-- [CHAR LIMIT=200] Manage applications, text for dialog when disabling notifications for an app --> <!-- [CHAR LIMIT=200] Manage applications, text for dialog when disabling notifications for an app -->

View File

@@ -116,6 +116,8 @@ public class InstalledAppDetails extends Fragment
private CanBeOnSdCardChecker mCanBeOnSdCardChecker; private CanBeOnSdCardChecker mCanBeOnSdCardChecker;
private View mRootView; private View mRootView;
private Button mUninstallButton; private Button mUninstallButton;
private View mMoreControlButtons;
private Button mSpecialDisableButton;
private boolean mMoveInProgress = false; private boolean mMoveInProgress = false;
private boolean mUpdatedSysApp = false; private boolean mUpdatedSysApp = false;
private Button mActivitiesButton; private Button mActivitiesButton;
@@ -141,6 +143,8 @@ public class InstalledAppDetails extends Fragment
private PackageMoveObserver mPackageMoveObserver; private PackageMoveObserver mPackageMoveObserver;
private boolean mDisableAfterUninstall;
private boolean mHaveSizes = false; private boolean mHaveSizes = false;
private long mLastCodeSize = -1; private long mLastCodeSize = -1;
private long mLastDataSize = -1; private long mLastDataSize = -1;
@@ -174,6 +178,7 @@ public class InstalledAppDetails extends Fragment
private static final int DLG_MOVE_FAILED = DLG_BASE + 6; private static final int DLG_MOVE_FAILED = DLG_BASE + 6;
private static final int DLG_DISABLE = DLG_BASE + 7; private static final int DLG_DISABLE = DLG_BASE + 7;
private static final int DLG_DISABLE_NOTIFICATIONS = DLG_BASE + 8; private static final int DLG_DISABLE_NOTIFICATIONS = DLG_BASE + 8;
private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 9;
// Menu identifiers // Menu identifiers
public static final int UNINSTALL_ALL_USERS_MENU = 1; public static final int UNINSTALL_ALL_USERS_MENU = 1;
@@ -309,14 +314,8 @@ public class InstalledAppDetails extends Fragment
} }
} }
private void initUninstallButtons() { private boolean handleDisableable(Button button) {
mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; boolean disableable = false;
boolean enabled = true;
if (mUpdatedSysApp) {
mUninstallButton.setText(R.string.app_factory_reset);
} else {
if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
enabled = false;
try { try {
// Try to prevent the user from bricking their phone // Try to prevent the user from bricking their phone
// by not allowing disabling of apps signed with the // by not allowing disabling of apps signed with the
@@ -329,17 +328,35 @@ public class InstalledAppDetails extends Fragment
List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0); List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
if ((homes != null && homes.size() > 0) || isThisASystemPackage()) { if ((homes != null && homes.size() > 0) || isThisASystemPackage()) {
// Disable button for core system applications. // Disable button for core system applications.
mUninstallButton.setText(R.string.disable_text); button.setText(R.string.disable_text);
} else if (mAppEntry.info.enabled) { } else if (mAppEntry.info.enabled) {
mUninstallButton.setText(R.string.disable_text); button.setText(R.string.disable_text);
enabled = true; disableable = true;
} else { } else {
mUninstallButton.setText(R.string.enable_text); button.setText(R.string.enable_text);
enabled = true; disableable = true;
} }
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Unable to get package info", e); Log.w(TAG, "Unable to get package info", e);
} }
return disableable;
}
private void initUninstallButtons() {
mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
boolean enabled = true;
if (mUpdatedSysApp) {
mUninstallButton.setText(R.string.app_factory_reset);
boolean specialDisable = false;
if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
specialDisable = handleDisableable(mSpecialDisableButton);
mSpecialDisableButton.setOnClickListener(this);
}
mMoreControlButtons.setVisibility(specialDisable ? View.VISIBLE : View.GONE);
} else {
mMoreControlButtons.setVisibility(View.GONE);
if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
enabled = handleDisableable(mUninstallButton);
} else if ((mPackageInfo.applicationInfo.flags } else if ((mPackageInfo.applicationInfo.flags
& ApplicationInfo.FLAG_INSTALLED) == 0) { & ApplicationInfo.FLAG_INSTALLED) == 0) {
mUninstallButton.setText(R.string.uninstall_text); mUninstallButton.setText(R.string.uninstall_text);
@@ -428,6 +445,12 @@ public class InstalledAppDetails extends Fragment
mUninstallButton = (Button)btnPanel.findViewById(R.id.right_button); mUninstallButton = (Button)btnPanel.findViewById(R.id.right_button);
mForceStopButton.setEnabled(false); mForceStopButton.setEnabled(false);
// Get More Control button panel
mMoreControlButtons = view.findViewById(R.id.more_control_buttons_panel);
mMoreControlButtons.findViewById(R.id.left_button).setVisibility(View.INVISIBLE);
mSpecialDisableButton = (Button)mMoreControlButtons.findViewById(R.id.right_button);
mMoreControlButtons.setVisibility(View.GONE);
// Initialize clear data and move install location buttons // Initialize clear data and move install location buttons
View data_buttons_panel = view.findViewById(R.id.data_buttons_panel); View data_buttons_panel = view.findViewById(R.id.data_buttons_panel);
mClearDataButton = (Button) data_buttons_panel.findViewById(R.id.right_button); mClearDataButton = (Button) data_buttons_panel.findViewById(R.id.right_button);
@@ -478,7 +501,7 @@ public class InstalledAppDetails extends Fragment
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
int menuId = item.getItemId(); int menuId = item.getItemId();
if (menuId == UNINSTALL_ALL_USERS_MENU) { if (menuId == UNINSTALL_ALL_USERS_MENU) {
uninstallPkg(mAppEntry.info.packageName, true); uninstallPkg(mAppEntry.info.packageName, true, false);
return true; return true;
} }
return false; return false;
@@ -488,6 +511,20 @@ public class InstalledAppDetails extends Fragment
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_UNINSTALL) { if (requestCode == REQUEST_UNINSTALL) {
if (mDisableAfterUninstall) {
mDisableAfterUninstall = false;
try {
ApplicationInfo ainfo = getActivity().getPackageManager().getApplicationInfo(
mAppEntry.info.packageName, PackageManager.GET_UNINSTALLED_PACKAGES
| PackageManager.GET_DISABLED_COMPONENTS);
if ((ainfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0) {
new DisableChanger(this, mAppEntry.info,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
.execute((Object)null);
}
} catch (NameNotFoundException e) {
}
}
if (!refreshUi()) { if (!refreshUi()) {
setIntentAndFinish(true, true); setIntentAndFinish(true, true);
} }
@@ -777,7 +814,14 @@ public class InstalledAppDetails extends Fragment
} else if (!mShowUninstalled) { } else if (!mShowUninstalled) {
// All other times: if we did not start out with the app uninstalled, // All other times: if we did not start out with the app uninstalled,
// then if it becomes uninstalled we want to go away. // then if it becomes uninstalled we want to go away.
return (mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0; try {
ApplicationInfo ainfo = getActivity().getPackageManager().getApplicationInfo(
mAppEntry.info.packageName, PackageManager.GET_UNINSTALLED_PACKAGES
| PackageManager.GET_DISABLED_COMPONENTS);
return (ainfo.flags&ApplicationInfo.FLAG_INSTALLED) != 0;
} catch (NameNotFoundException e) {
return false;
}
} }
return true; return true;
@@ -924,6 +968,7 @@ public class InstalledAppDetails extends Fragment
mMoveAppButton.setText(R.string.moving); mMoveAppButton.setText(R.string.moving);
mMoveAppButton.setEnabled(false); mMoveAppButton.setEnabled(false);
mUninstallButton.setEnabled(false); mUninstallButton.setEnabled(false);
mSpecialDisableButton.setEnabled(false);
} }
} }
@@ -1015,7 +1060,8 @@ public class InstalledAppDetails extends Fragment
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
// Clear user data here // Clear user data here
getOwner().uninstallPkg(getOwner().mAppEntry.info.packageName, false); getOwner().uninstallPkg(getOwner().mAppEntry.info.packageName,
false, false);
} }
}) })
.setNegativeButton(R.string.dlg_cancel, null) .setNegativeButton(R.string.dlg_cancel, null)
@@ -1106,17 +1152,33 @@ public class InstalledAppDetails extends Fragment
} }
}) })
.create(); .create();
case DLG_SPECIAL_DISABLE:
return new AlertDialog.Builder(getActivity())
.setTitle(getActivity().getText(R.string.app_special_disable_dlg_title))
.setIconAttribute(android.R.attr.alertDialogIcon)
.setMessage(getActivity().getText(R.string.app_special_disable_dlg_text))
.setPositiveButton(R.string.dlg_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Clear user data here
getOwner().uninstallPkg(getOwner().mAppEntry.info.packageName,
false, true);
}
})
.setNegativeButton(R.string.dlg_cancel, null)
.create();
} }
throw new IllegalArgumentException("unknown id " + id); throw new IllegalArgumentException("unknown id " + id);
} }
} }
private void uninstallPkg(String packageName, boolean allUsers) { private void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
// Create new intent to launch Uninstaller activity // Create new intent to launch Uninstaller activity
Uri packageURI = Uri.parse("package:"+packageName); Uri packageURI = Uri.parse("package:"+packageName);
Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI); Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI);
uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers); uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
startActivityForResult(uninstallIntent, REQUEST_UNINSTALL); startActivityForResult(uninstallIntent, REQUEST_UNINSTALL);
mDisableAfterUninstall = andDisable;
} }
private void forceStopPackage(String pkgName) { private void forceStopPackage(String pkgName) {
@@ -1230,9 +1292,11 @@ public class InstalledAppDetails extends Fragment
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
} }
} else { } else {
uninstallPkg(packageName, false); uninstallPkg(packageName, false, false);
} }
} }
} else if(v == mSpecialDisableButton) {
showDialogInner(DLG_SPECIAL_DISABLE, 0);
} else if(v == mActivitiesButton) { } else if(v == mActivitiesButton) {
mPm.clearPackagePreferredActivities(packageName); mPm.clearPackagePreferredActivities(packageName);
try { try {