Merge "Delete clone app when primary app is being uninstalled."

This commit is contained in:
Ankita Vyas
2023-01-24 08:36:43 +00:00
committed by Android (Google) Code Review
5 changed files with 42 additions and 8 deletions

View File

@@ -143,6 +143,8 @@
<!-- [CHAR LIMIT=100] -->
<string name="uninstall_done_app">Uninstalled <xliff:g id="package_label">%1$s</xliff:g></string>
<!-- [CHAR LIMIT=100] -->
<string name="uninstall_done_clone_app">Deleted <xliff:g id="package_label">%1$s</xliff:g> clone</string>
<!-- [CHAR LIMIT=100] -->
<string name="uninstall_failed">Uninstall unsuccessful.</string>
<!-- [CHAR LIMIT=100] -->
<string name="uninstall_failed_app">Uninstalling <xliff:g id="package_label">%1$s</xliff:g> unsuccessful.</string>

View File

@@ -49,6 +49,7 @@ public class UninstallFinish extends BroadcastReceiver {
static final String EXTRA_UNINSTALL_ID = "com.android.packageinstaller.extra.UNINSTALL_ID";
static final String EXTRA_APP_LABEL = "com.android.packageinstaller.extra.APP_LABEL";
static final String EXTRA_IS_CLONE_APP = "com.android.packageinstaller.extra.IS_CLONE_APP";
@Override
public void onReceive(Context context, Intent intent) {
@@ -84,7 +85,10 @@ public class UninstallFinish extends BroadcastReceiver {
case PackageInstaller.STATUS_SUCCESS:
notificationManager.cancel(uninstallId);
Toast.makeText(context, context.getString(R.string.uninstall_done_app, appLabel),
boolean isCloneApp = intent.getBooleanExtra(EXTRA_IS_CLONE_APP, false);
Toast.makeText(context, isCloneApp
? context.getString(R.string.uninstall_done_clone_app, appLabel)
: context.getString(R.string.uninstall_done_app, appLabel),
Toast.LENGTH_LONG).show();
return;
case PackageInstaller.STATUS_FAILURE_BLOCKED: {

View File

@@ -67,6 +67,7 @@ public class UninstallerActivity extends Activity {
private static final String TAG = "UninstallerActivity";
private static final String UNINSTALLING_CHANNEL = "uninstalling";
private boolean mIsClonedApp;
public static class DialogInfo {
public ApplicationInfo appInfo;
@@ -277,6 +278,14 @@ public class UninstallerActivity extends Activity {
fragment.show(ft, "dialog");
}
/**
* Starts uninstall of app.
*/
public void startUninstallProgress(boolean keepData, boolean isClonedApp) {
mIsClonedApp = isClonedApp;
startUninstallProgress(keepData);
}
public void startUninstallProgress(boolean keepData) {
boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false);
CharSequence label = mDialogInfo.appInfo.loadSafeLabel(getPackageManager());
@@ -329,6 +338,7 @@ public class UninstallerActivity extends Activity {
broadcastIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo);
broadcastIntent.putExtra(UninstallFinish.EXTRA_APP_LABEL, label);
broadcastIntent.putExtra(UninstallFinish.EXTRA_UNINSTALL_ID, uninstallId);
broadcastIntent.putExtra(UninstallFinish.EXTRA_IS_CLONE_APP, mIsClonedApp);
PendingIntent pendingIntent =
PendingIntent.getBroadcast(this, uninstallId, broadcastIntent,
@@ -343,7 +353,10 @@ public class UninstallerActivity extends Activity {
Notification uninstallingNotification =
(new Notification.Builder(this, UNINSTALLING_CHANNEL))
.setSmallIcon(R.drawable.ic_remove).setProgress(0, 1, true)
.setContentTitle(getString(R.string.uninstalling_app, label)).setOngoing(true)
.setContentTitle(mIsClonedApp
? getString(R.string.uninstalling_cloned_app, label)
: getString(R.string.uninstalling_app, label))
.setOngoing(true)
.build();
notificationManager.notify(uninstallId, uninstallingNotification);

View File

@@ -54,6 +54,7 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
private static final String LOG_TAG = UninstallAlertDialogFragment.class.getSimpleName();
private @Nullable CheckBox mKeepData;
private boolean mIsClonedApp;
/**
* Get number of bytes of the app data of the package.
@@ -125,7 +126,6 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
messageBuilder.append(" ").append(appLabel).append(".\n\n");
}
}
boolean isClonedApp = false;
final boolean isUpdate =
((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
@@ -154,7 +154,7 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
userName));
} else if (customUserManager.isUserOfType(USER_TYPE_PROFILE_CLONE)
&& customUserManager.isSameProfileGroup(dialogInfo.user, myUserHandle)) {
isClonedApp = true;
mIsClonedApp = true;
messageBuilder.append(getString(
R.string.uninstall_application_text_current_user_clone_profile));
} else {
@@ -162,7 +162,7 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
getString(R.string.uninstall_application_text_user, userName));
}
} else if (isCloneProfile(myUserHandle)) {
isClonedApp = true;
mIsClonedApp = true;
messageBuilder.append(getString(
R.string.uninstall_application_text_current_user_clone_profile));
} else {
@@ -177,7 +177,7 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
}
}
if (isClonedApp) {
if (mIsClonedApp) {
dialogBuilder.setTitle(getString(R.string.cloned_app_label, appLabel));
} else {
dialogBuilder.setTitle(appLabel);
@@ -236,7 +236,7 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
UserManager userManager = getContext().getSystemService(UserManager.class);
List<UserHandle> profiles = userManager.getUserProfiles();
for (UserHandle userHandle : profiles) {
if (!Process.myUserHandle().equals(UserHandle.SYSTEM) && isCloneProfile(userHandle)) {
if (!userHandle.equals(UserHandle.SYSTEM) && isCloneProfile(userHandle)) {
cloneUser = userHandle;
break;
}
@@ -260,7 +260,7 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
public void onClick(DialogInterface dialog, int which) {
if (which == Dialog.BUTTON_POSITIVE) {
((UninstallerActivity) getActivity()).startUninstallProgress(
mKeepData != null && mKeepData.isChecked());
mKeepData != null && mKeepData.isChecked(), mIsClonedApp);
} else {
((UninstallerActivity) getActivity()).dispatchAborted();
}

View File

@@ -774,6 +774,21 @@ final class DeletePackageHelper {
if (!deleteAllUsers) {
returnCode = deletePackageX(internalPackageName, versionCode,
userId, deleteFlags, false /*removedBySystem*/);
// Get a list of child user profiles and delete if package is
// present in clone profile.
int[] childUserIds = mUserManagerInternal.getProfileIds(userId, true);
for (int childId : childUserIds) {
if (childId != userId) {
UserInfo userInfo = mUserManagerInternal.getUserInfo(childId);
if (userInfo != null && userInfo.isCloneProfile()) {
returnCode = deletePackageX(internalPackageName, versionCode,
childId, deleteFlags, false /*removedBySystem*/);
break;
}
}
}
} else {
int[] blockUninstallUserIds = getBlockUninstallForUsers(innerSnapshot,
internalPackageName, users);