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

Commit 70b31313 authored by Jeremy Sim's avatar Jeremy Sim Committed by Android (Google) Code Review
Browse files

Merge "Improve app pairs disabled state" into main

parents 6e3541e7 3c1ee0da
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.PendingIntent;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherUserInfo;
@@ -156,6 +157,13 @@ public class ApiWrapper {
        }
    }

    /**
     * Checks if an activity is flagged as non-resizeable.
     */
    public static boolean isNonResizeableActivity(LauncherActivityInfo lai) {
        return lai.getActivityInfo().resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
    }

    private static class NoopDrawable extends ColorDrawable {
        @Override
        public int getIntrinsicHeight() {
+4 −0
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@
    <string name="save_app_pair">Save app pair</string>
    <!-- App pair default title -->
    <string name="app_pair_default_title"><xliff:g id="app1" example="Chrome">%1$s</xliff:g> | <xliff:g id="app2" example="YouTube">%2$s</xliff:g></string>
    <!-- Displayed when an app pair can't launch at this screen size [CHAR_LIMIT=none] -->
    <string name="app_pair_unlaunchable_at_screen_size">This pair isn\'t supported at this screen size</string>
    <!-- Displayed when an app pair can't launch at this screen size, but user can unfold device to restore functionality [CHAR_LIMIT=none] -->
    <string name="app_pair_needs_unfold">Unfold your device to use this pair</string>

    <!-- Widgets -->
    <!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
+51 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.launcher3.apppairs;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
@@ -33,11 +34,13 @@ import com.android.launcher3.R;
import com.android.launcher3.Reorderable;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.views.ActivityContext;

import java.util.Collections;
import java.util.Comparator;
import java.util.function.Predicate;

/**
 * A {@link android.widget.FrameLayout} used to represent an app pair icon on the workspace.
@@ -48,6 +51,11 @@ import java.util.Comparator;
public class AppPairIcon extends FrameLayout implements DraggableView, Reorderable {
    private static final String TAG = "AppPairIcon";

    /**
     * Indicates that the app pair is currently launchable on the current screen.
     */
    private boolean mIsLaunchableAtScreenSize = true;

    // A view that holds the app pair icon graphic.
    private AppPairIconGraphic mIconGraphic;
    // A view that holds the app pair's title.
@@ -86,6 +94,13 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
        icon.setOnClickListener(activity.getItemOnClickListener());
        icon.mInfo = appPairInfo;

        if (icon.mInfo.contents.size() != 2) {
            Log.wtf(TAG, "AppPair contents not 2, size: " + icon.mInfo.contents.size());
            return icon;
        }

        icon.checkScreenSize();

        // Set up icon drawable area
        icon.mIconGraphic = icon.findViewById(R.id.app_pair_icon_graphic);
        icon.mIconGraphic.init(activity.getDeviceProfile(), icon);
@@ -109,11 +124,6 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
     * Returns a formatted accessibility title for app pairs.
     */
    public String getAccessibilityTitle(FolderInfo appPairInfo) {
        if (appPairInfo.contents.size() != 2) {
            Log.wtf(TAG, "AppPair contents not 2, size: " + appPairInfo.contents.size());
            return "";
        }

        CharSequence app1 = appPairInfo.contents.get(0).title;
        CharSequence app2 = appPairInfo.contents.get(1).title;
        return getContext().getString(R.string.app_pair_name_format, app1, app2);
@@ -167,4 +177,40 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
    public View getIconDrawableArea() {
        return mIconGraphic;
    }

    public boolean isLaunchableAtScreenSize() {
        return mIsLaunchableAtScreenSize;
    }

    /**
     * Checks if the app pair is launchable in the current device configuration.
     *
     * App pairs can be "disabled" in two ways:
     * 1) One of the member WorkspaceItemInfos is disabled (i.e. the app software itself is paused
     * by the user or can't be launched).
     * 2) This specific instance of an app pair can't be launched due to screen size requirements.
     *
     * This method checks and updates #2. Both #1 and #2 are checked when app pairs are drawn
     * {@link AppPairIconGraphic#dispatchDraw(Canvas)} or clicked on
     * {@link com.android.launcher3.touch.ItemClickHandler#onClickAppPairIcon(View)}
     */
    public void checkScreenSize() {
        DeviceProfile dp = ActivityContext.lookupContext(getContext()).getDeviceProfile();
        // If user is on a small screen, we can't launch if either of the apps is non-resizeable
        mIsLaunchableAtScreenSize =
                dp.isTablet || getInfo().contents.stream().noneMatch(
                        wii -> wii.hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE));
    }

    /**
     * Called when WorkspaceItemInfos get updated, and the app pair icon may need to be redrawn.
     */
    public void maybeRedrawForWorkspaceUpdate(Predicate<WorkspaceItemInfo> itemCheck) {
        // If either of the app pair icons return true on the predicate (i.e. in the list of
        // updated apps), redraw the icon graphic (icon background and both icons).
        if (getInfo().contents.stream().anyMatch(itemCheck)) {
            checkScreenSize();
            mIconGraphic.invalidate();
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ class AppPairIconBackground extends Drawable {

    @Override
    public void setAlpha(int i) {
        // Required by Drawable but not used.
        mBackgroundPaint.setAlpha(i);
    }

    @Override
+11 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
        private const val CENTER_CHANNEL_SCALE = 1 / 30f
        private const val BIG_RADIUS_SCALE = 1 / 5f
        private const val SMALL_RADIUS_SCALE = 1 / 15f
        // Disabled alpha is 38%, or 97/255
        private const val DISABLED_ALPHA = 97
        private const val ENABLED_ALPHA = 255
    }

    // App pair icons are slightly smaller than regular icons, so we pad the icon by this much on
@@ -133,7 +136,13 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr

    override fun dispatchDraw(canvas: Canvas) {
        super.dispatchDraw(canvas)

        val drawAlpha =
            if (!parentIcon.isLaunchableAtScreenSize || parentIcon.info.isDisabled) DISABLED_ALPHA
            else ENABLED_ALPHA

        // Draw background
        appPairBackground.alpha = drawAlpha
        appPairBackground.draw(canvas)

        // Make sure icons are loaded and fresh
@@ -147,6 +156,7 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
        } else {
            canvas.translate(width / 2f - memberIconSize / 2f, innerPadding)
        }
        appIcon1?.alpha = drawAlpha
        appIcon1?.draw(canvas)
        canvas.restore()

@@ -164,6 +174,7 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
                height - (innerPadding + memberIconSize)
            )
        }
        appIcon2?.alpha = drawAlpha
        appIcon2?.draw(canvas)
        canvas.restore()
    }
Loading