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

Commit 8ee9076f authored by Anushree Ganjam's avatar Anushree Ganjam Committed by Android (Google) Code Review
Browse files

Merge "[PS] Show "Uninstall" in Long Press menu for Private Space apps." into main

parents dd8de0a6 45ef544a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.DONT_SUGGEST_APP;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.PRIVATE_PROFILE_INSTALL;
import static com.android.launcher3.popup.SystemShortcut.UNINSTALL_APP;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.MINUS_ONE_PAGE_PROGRESS_INDEX;
@@ -437,6 +438,9 @@ public class QuickstepLauncher extends Launcher {
        if (Flags.enableShortcutDontSuggestApp()) {
            shortcuts.add(DONT_SUGGEST_APP);
        }
        if (Flags.enablePrivateSpace()) {
            shortcuts.add(UNINSTALL_APP);
        }
        return shortcuts.stream();
    }

+30 −14
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.logging.FileLog;
@@ -43,6 +45,7 @@ import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;

@@ -176,6 +179,10 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
        if (uninstallDisabled) {
            return INVALID;
        }
        if (Flags.enablePrivateSpace() && UserCache.getInstance(getContext()).getUserInfo(
                info.user).isPrivate()) {
            return INVALID;
        }

        if (info instanceof ItemInfoWithIcon) {
            ItemInfoWithIcon iconInfo = (ItemInfoWithIcon) info;
@@ -184,7 +191,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
                return INVALID;
            }
        }
        if (getUninstallTarget(info) == null) {
        if (getUninstallTarget(getContext(), info) == null) {
            return INVALID;
        }
        return UNINSTALL;
@@ -193,7 +200,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
    /**
     * @return the component name that should be uninstalled or null.
     */
    private ComponentName getUninstallTarget(ItemInfo item) {
    public static ComponentName getUninstallTarget(Context context, ItemInfo item) {
        Intent intent = null;
        UserHandle user = null;
        if (item != null &&
@@ -202,7 +209,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
            user = item.user;
        }
        if (intent != null) {
            LauncherActivityInfo info = getContext().getSystemService(LauncherApps.class)
            LauncherActivityInfo info = context.getSystemService(LauncherApps.class)
                    .resolveActivity(intent, user);
            if (info != null
                    && (info.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
@@ -280,7 +287,8 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
            if (FeatureFlags.ENABLE_DISMISS_PREDICTION_UNDO.get()) {
                CharSequence announcement = getContext().getString(R.string.item_removed);
                mDropTargetHandler
                        .dismissPrediction(announcement, () -> {}, () -> {
                        .dismissPrediction(announcement, () -> {
                        }, () -> {
                            mStatsLogManager.logger()
                                    .withInstanceId(instanceId)
                                    .withItemInfo(info)
@@ -290,22 +298,30 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
            return null;
        }

        ComponentName cn = getUninstallTarget(info);
        return performUninstall(getContext(), getUninstallTarget(getContext(), info), info);
    }

    /**
     * Performs uninstall and returns the target component for the {@link ItemInfo} or null if
     * the uninstall was not performed.
     */
    public static ComponentName performUninstall(Context context, @Nullable ComponentName cn,
            ItemInfo info) {
        if (cn == null) {
            // System applications cannot be installed. For now, show a toast explaining that.
            // We may give them the option of disabling apps this way.
            Toast.makeText(
                    getContext(),
                    context,
                    R.string.uninstall_system_app_text,
                    Toast.LENGTH_SHORT
            ).show();
            return null;
        }
        try {
            Intent i = Intent.parseUri(getContext().getString(R.string.delete_package_intent), 0)
            Intent i = Intent.parseUri(context.getString(R.string.delete_package_intent), 0)
                    .setData(Uri.fromParts("package", cn.getPackageName(), cn.getClassName()))
                    .putExtra(Intent.EXTRA_USER, info.user);
            getContext().startActivity(i);
            context.startActivity(i);
            FileLog.d(TAG, "start uninstall activity " + cn.getPackageName());
            return cn;
        } catch (URISyntaxException e) {
+4 −1
Original line number Diff line number Diff line
@@ -717,7 +717,10 @@ public class StatsLogManager implements ResourceBasedOverride {
        LAUNCHER_PRIVATE_SPACE_INSTALL_APP_BUTTON_TAP(1605),

        @UiEvent(doc = "User attempted to create split screen with a widget")
        LAUNCHER_SPLIT_WIDGET_ATTEMPT(1604)
        LAUNCHER_SPLIT_WIDGET_ATTEMPT(1604),

        @UiEvent(doc = "User tapped on private space uninstall system shortcut.")
        LAUNCHER_PRIVATE_SPACE_UNINSTALL_SYSTEM_SHORTCUT_TAP(1608),

        // ADD MORE
        ;
+54 −9
Original line number Diff line number Diff line
package com.android.launcher3.popup;

import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_PRIVATE_SPACE_INSTALL_SYSTEM_SHORTCUT_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_PRIVATE_SPACE_UNINSTALL_SYSTEM_SHORTCUT_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DONT_SUGGEST_APP_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP;
@@ -17,17 +18,21 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.Flags;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.SecondaryDropTarget;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.PrivateProfileManager;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
@@ -301,16 +306,11 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
        }
    }

    public static final Factory<Launcher> DONT_SUGGEST_APP = new Factory<Launcher>() {
        @Nullable
        @Override
        public SystemShortcut<Launcher> getShortcut(Launcher activity, ItemInfo itemInfo,
                View originalView) {
    public static final Factory<Launcher> DONT_SUGGEST_APP = (activity, itemInfo, originalView) -> {
        if (!itemInfo.isPredictedItem()) {
            return null;
        }
        return new DontSuggestApp(activity, itemInfo, originalView);
        }
    };

    private static class DontSuggestApp extends SystemShortcut<Launcher> {
@@ -329,6 +329,51 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
        }
    }

    public static final Factory<Launcher> UNINSTALL_APP = (activity, itemInfo, originalView) -> {
        if (!Flags.enablePrivateSpace()) {
            return null;
        }
        if (!UserCache.getInstance(activity.getApplicationContext()).getUserInfo(
                itemInfo.user).isPrivate()) {
            // If app is not Private Space app.
            return null;
        }
        ComponentName cn = SecondaryDropTarget.getUninstallTarget(activity.getApplicationContext(),
                itemInfo);
        if (cn == null) {
            // If component name is null, don't show uninstall shortcut.
            // System apps will have component name as null.
            return null;
        }
        return new UninstallApp(activity, itemInfo, originalView, cn);
    };

    private static class UninstallApp extends SystemShortcut<Launcher> {
        private static final String TAG = "UninstallApp";
        Context mContext;
        @NonNull
        ComponentName mComponentName;

        UninstallApp(Launcher target, ItemInfo itemInfo, View originalView,
                @NonNull ComponentName cn) {
            super(R.drawable.ic_uninstall_no_shadow, R.string.uninstall_drop_target_label, target,
                    itemInfo, originalView);
            mContext = target.getApplicationContext();
            mComponentName = cn;

        }

        @Override
        public void onClick(View view) {
            dismissTaskMenuView(mTarget);
            SecondaryDropTarget.performUninstall(mContext, mComponentName, mItemInfo);
            mTarget.getStatsLogManager()
                    .logger()
                    .withItemInfo(mItemInfo)
                    .log(LAUNCHER_PRIVATE_SPACE_UNINSTALL_SYSTEM_SHORTCUT_TAP);
        }
    }

    public static <T extends Context & ActivityContext> void dismissTaskMenuView(T activity) {
        AbstractFloatingView.closeOpenViews(activity, true,
            AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);