Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5610199b authored by Ankita Vyas's avatar Ankita Vyas
Browse files

Delete clone app when primary app is being uninstalled.

In followup cl, will generalize this to any profile by adding a new
UserProperty.

Also contains fix in dialog fragment to pass correct userId.

Bug: 265622990
Test: manual
Change-Id: I4fc4d137bb546b55010060eed248ae6060446c19
parent 092ca54a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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>
+5 −1
Original line number Diff line number Diff line
@@ -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: {
+14 −1
Original line number Diff line number Diff line
@@ -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);
+6 −6
Original line number Diff line number Diff line
@@ -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();
        }
+15 −0
Original line number Diff line number Diff line
@@ -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);