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

Commit ec1a1a70 authored by Miranda Kephart's avatar Miranda Kephart
Browse files

Update clipboard UI to align with new screenshot UI

Bug: 329659738
Flag: ACONFIG com.android.systemui.screenshot_shelf_ui2 TEAMFOOD
Test: manual (visual change)
Change-Id: If9cb6ddc6163aa7954a1302a89f1a33f7942aaf6
parent dab379e0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -16,6 +16,6 @@

<shape xmlns:android = "http://schemas.android.com/apk/res/android">
    <size
        android:width = "@dimen/overlay_action_chip_margin_start"
        android:width = "@dimen/shelf_action_chip_margin_start"
        android:height = "0dp"/>
</shape>
+191 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2021 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<com.android.systemui.clipboardoverlay.ClipboardOverlayView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/clipboard_ui"
    android:theme="@style/FloatingOverlay"
    android:alpha="0"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:contentDescription="@string/clipboard_overlay_window_name">
    <FrameLayout
        android:id="@+id/actions_container_background"
        android:visibility="gone"
        android:layout_height="0dp"
        android:layout_width="0dp"
        android:elevation="4dp"
        android:background="@drawable/shelf_action_chip_container_background"
        android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
        android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/actions_container"
        app:layout_constraintEnd_toEndOf="@+id/actions_container"
        app:layout_constraintBottom_toBottomOf="parent"/>
    <HorizontalScrollView
        android:id="@+id/actions_container"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
        android:paddingEnd="@dimen/overlay_action_container_padding_end"
        android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
        android:elevation="4dp"
        android:scrollbars="none"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintWidth_percent="1.0"
        app:layout_constraintWidth_max="wrap"
        app:layout_constraintStart_toEndOf="@+id/preview_border"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="@id/actions_container_background">
        <LinearLayout
            android:id="@+id/actions"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingStart="@dimen/shelf_action_chip_margin_start"
            android:showDividers="middle"
            android:divider="@drawable/shelf_action_chip_divider"
            android:animateLayoutChanges="true">
            <include layout="@layout/shelf_action_chip"
                     android:id="@+id/share_chip"/>
            <include layout="@layout/shelf_action_chip"
                     android:id="@+id/remote_copy_chip"/>
        </LinearLayout>
    </HorizontalScrollView>
    <View
        android:id="@+id/preview_border"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="@dimen/overlay_preview_container_margin"
        android:layout_marginTop="@dimen/overlay_border_width_neg"
        android:layout_marginEnd="@dimen/overlay_border_width_neg"
        android:layout_marginBottom="@dimen/overlay_preview_container_margin"
        android:elevation="7dp"
        android:background="@drawable/overlay_border"
        app:layout_constraintStart_toStartOf="@id/actions_container_background"
        app:layout_constraintTop_toTopOf="@id/clipboard_preview"
        app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
        app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
    <FrameLayout
        android:id="@+id/clipboard_preview"
        android:layout_width="@dimen/clipboard_preview_size"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/overlay_border_width"
        android:layout_marginBottom="@dimen/overlay_border_width"
        android:layout_gravity="center"
        android:elevation="7dp"
        android:background="@drawable/overlay_preview_background"
        android:clipChildren="true"
        android:clipToOutline="true"
        android:clipToPadding="true"
        app:layout_constraintStart_toStartOf="@id/preview_border"
        app:layout_constraintBottom_toBottomOf="@id/preview_border">
        <TextView android:id="@+id/text_preview"
                  android:textFontWeight="500"
                  android:padding="8dp"
                  android:gravity="center|start"
                  android:ellipsize="end"
                  android:autoSizeTextType="uniform"
                  android:autoSizeMinTextSize="@dimen/clipboard_overlay_min_font"
                  android:autoSizeMaxTextSize="@dimen/clipboard_overlay_max_font"
                  android:textColor="?attr/overlayButtonTextColor"
                  android:textColorLink="?attr/overlayButtonTextColor"
                  android:background="?androidprv:attr/colorAccentSecondary"
                  android:layout_width="@dimen/clipboard_preview_size"
                  android:layout_height="@dimen/clipboard_preview_size"/>
        <ImageView
            android:id="@+id/image_preview"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true"
            android:contentDescription="@string/clipboard_image_preview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/hidden_preview"
            android:visibility="gone"
            android:textFontWeight="500"
            android:padding="8dp"
            android:gravity="center"
            android:textSize="14sp"
            android:textColor="?attr/overlayButtonTextColor"
            android:background="?androidprv:attr/colorAccentSecondary"
            android:layout_width="@dimen/clipboard_preview_size"
            android:layout_height="@dimen/clipboard_preview_size"/>
    </FrameLayout>
    <LinearLayout
        android:id="@+id/minimized_preview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:elevation="7dp"
        android:padding="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
        android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
        android:background="@drawable/clipboard_minimized_background">
        <ImageView
            android:src="@drawable/ic_content_paste"
            android:tint="?attr/overlayButtonTextColor"
            android:layout_width="24dp"
            android:layout_height="24dp"/>
        <ImageView
            android:src="@*android:drawable/ic_chevron_end"
            android:tint="?attr/overlayButtonTextColor"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:paddingEnd="-8dp"
            android:paddingStart="-4dp"/>
    </LinearLayout>
    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/clipboard_content_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:barrierDirection="top"
        app:constraint_referenced_ids="clipboard_preview,minimized_preview"/>
    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/clipboard_content_end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:barrierDirection="end"
        app:constraint_referenced_ids="clipboard_preview,minimized_preview"/>
    <FrameLayout
        android:id="@+id/dismiss_button"
        android:layout_width="@dimen/overlay_dismiss_button_tappable_size"
        android:layout_height="@dimen/overlay_dismiss_button_tappable_size"
        android:elevation="10dp"
        android:visibility="gone"
        android:alpha="0"
        app:layout_constraintStart_toEndOf="@id/clipboard_content_end"
        app:layout_constraintEnd_toEndOf="@id/clipboard_content_end"
        app:layout_constraintTop_toTopOf="@id/clipboard_content_top"
        app:layout_constraintBottom_toTopOf="@id/clipboard_content_top"
        android:contentDescription="@string/clipboard_dismiss_description">
        <ImageView
            android:id="@+id/dismiss_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/overlay_dismiss_button_margin"
            android:background="@drawable/circular_background"
            android:backgroundTint="?androidprv:attr/materialColorPrimaryFixedDim"
            android:tint="?androidprv:attr/materialColorOnPrimaryFixed"
            android:padding="4dp"
            android:src="@drawable/ic_close"/>
    </FrameLayout>
</com.android.systemui.clipboardoverlay.ClipboardOverlayView>
 No newline at end of file
+1 −0
Original line number Diff line number Diff line
@@ -426,6 +426,7 @@
    <dimen name="overlay_button_corner_radius">16dp</dimen>
    <!-- Margin between successive chips -->
    <dimen name="overlay_action_chip_margin_start">8dp</dimen>
    <dimen name="shelf_action_chip_margin_start">12dp</dimen>
    <dimen name="overlay_action_chip_padding_vertical">12dp</dimen>
    <dimen name="overlay_action_chip_icon_size">24sp</dimen>
    <!-- Padding on each side of the icon for icon-only chips -->
+98 −18
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.clipboardoverlay;

import static android.content.res.Configuration.ORIENTATION_PORTRAIT;

import static com.android.systemui.Flags.screenshotShelfUi2;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -25,6 +27,7 @@ import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.app.RemoteAction;
import android.content.Context;
import android.content.res.Resources;
@@ -36,6 +39,7 @@ import android.graphics.Region;
import android.graphics.drawable.Icon;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.MathUtils;
import android.util.TypedValue;
import android.view.DisplayCutout;
@@ -58,9 +62,15 @@ import com.android.systemui.res.R;
import com.android.systemui.screenshot.DraggableConstraintLayout;
import com.android.systemui.screenshot.FloatingWindowUtil;
import com.android.systemui.screenshot.OverlayActionChip;
import com.android.systemui.screenshot.ui.binder.ActionButtonViewBinder;
import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance;
import com.android.systemui.screenshot.ui.viewmodel.ActionButtonViewModel;

import java.util.ArrayList;

import kotlin.Unit;
import kotlin.jvm.functions.Function0;

/**
 * Handles the visual elements and animations for the clipboard overlay.
 */
@@ -85,7 +95,7 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {

    private final DisplayMetrics mDisplayMetrics;
    private final AccessibilityManager mAccessibilityManager;
    private final ArrayList<OverlayActionChip> mActionChips = new ArrayList<>();
    private final ArrayList<View> mActionChips = new ArrayList<>();

    private View mClipboardPreview;
    private ImageView mImagePreview;
@@ -93,11 +103,12 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {
    private TextView mHiddenPreview;
    private LinearLayout mMinimizedPreview;
    private View mPreviewBorder;
    private OverlayActionChip mShareChip;
    private OverlayActionChip mRemoteCopyChip;
    private View mShareChip;
    private View mRemoteCopyChip;
    private View mActionContainerBackground;
    private View mDismissButton;
    private LinearLayout mActionContainer;
    private ClipboardOverlayCallbacks mClipboardCallbacks;

    public ClipboardOverlayView(Context context) {
        this(context, null);
@@ -128,17 +139,7 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {
        mRemoteCopyChip = requireViewById(R.id.remote_copy_chip);
        mDismissButton = requireViewById(R.id.dismiss_button);

        mShareChip.setAlpha(1);
        mRemoteCopyChip.setAlpha(1);
        mShareChip.setContentDescription(mContext.getString(com.android.internal.R.string.share));

        mRemoteCopyChip.setIcon(
                Icon.createWithResource(mContext, R.drawable.ic_baseline_devices_24), true);
        mShareChip.setIcon(
                Icon.createWithResource(mContext, R.drawable.ic_screenshot_share), true);

        mRemoteCopyChip.setContentDescription(
                mContext.getString(R.string.clipboard_send_nearby_description));
        bindDefaultActionChips();

        mTextPreview.getViewTreeObserver().addOnPreDrawListener(() -> {
            int availableHeight = mTextPreview.getHeight()
@@ -149,15 +150,68 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {
        super.onFinishInflate();
    }

    private void bindDefaultActionChips() {
        if (screenshotShelfUi2()) {
            ActionButtonViewBinder.INSTANCE.bind(mRemoteCopyChip,
                    ActionButtonViewModel.Companion.withNextId(
                            new ActionButtonAppearance(
                                    Icon.createWithResource(mContext,
                                            R.drawable.ic_baseline_devices_24).loadDrawable(
                                            mContext),
                                    null,
                                    mContext.getString(R.string.clipboard_send_nearby_description)),
                            new Function0<>() {
                                @Override
                                public Unit invoke() {
                                    if (mClipboardCallbacks != null) {
                                        mClipboardCallbacks.onRemoteCopyButtonTapped();
                                    }
                                    return null;
                                }
                            }));
            ActionButtonViewBinder.INSTANCE.bind(mShareChip,
                    ActionButtonViewModel.Companion.withNextId(
                            new ActionButtonAppearance(
                                    Icon.createWithResource(mContext,
                                            R.drawable.ic_screenshot_share).loadDrawable(mContext),
                                    null, mContext.getString(com.android.internal.R.string.share)),
                            new Function0<>() {
                                @Override
                                public Unit invoke() {
                                    if (mClipboardCallbacks != null) {
                                        mClipboardCallbacks.onShareButtonTapped();
                                    }
                                    return null;
                                }
                            }));
        } else {
            mShareChip.setAlpha(1);
            mRemoteCopyChip.setAlpha(1);

            ((ImageView) mRemoteCopyChip.findViewById(R.id.overlay_action_chip_icon)).setImageIcon(
                    Icon.createWithResource(mContext, R.drawable.ic_baseline_devices_24));
            ((ImageView) mShareChip.findViewById(R.id.overlay_action_chip_icon)).setImageIcon(
                    Icon.createWithResource(mContext, R.drawable.ic_screenshot_share));

            mShareChip.setContentDescription(
                    mContext.getString(com.android.internal.R.string.share));
            mRemoteCopyChip.setContentDescription(
                    mContext.getString(R.string.clipboard_send_nearby_description));
        }
    }

    @Override
    public void setCallbacks(SwipeDismissCallbacks callbacks) {
        super.setCallbacks(callbacks);
        ClipboardOverlayCallbacks clipboardCallbacks = (ClipboardOverlayCallbacks) callbacks;
        if (!screenshotShelfUi2()) {
            mShareChip.setOnClickListener(v -> clipboardCallbacks.onShareButtonTapped());
        mDismissButton.setOnClickListener(v -> clipboardCallbacks.onDismissButtonTapped());
            mRemoteCopyChip.setOnClickListener(v -> clipboardCallbacks.onRemoteCopyButtonTapped());
        }
        mDismissButton.setOnClickListener(v -> clipboardCallbacks.onDismissButtonTapped());
        mClipboardPreview.setOnClickListener(v -> clipboardCallbacks.onPreviewTapped());
        mMinimizedPreview.setOnClickListener(v -> clipboardCallbacks.onMinimizedViewTapped());
        mClipboardCallbacks = clipboardCallbacks;
    }

    void setEditAccessibilityAction(boolean editable) {
@@ -285,7 +339,7 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {
    }

    void resetActionChips() {
        for (OverlayActionChip chip : mActionChips) {
        for (View chip : mActionChips) {
            mActionContainer.removeView(chip);
        }
        mActionChips.clear();
@@ -437,7 +491,12 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {

    void setActionChip(RemoteAction action, Runnable onFinish) {
        mActionContainerBackground.setVisibility(View.VISIBLE);
        OverlayActionChip chip = constructActionChip(action, onFinish);
        View chip;
        if (screenshotShelfUi2()) {
            chip = constructShelfActionChip(action, onFinish);
        } else {
            chip = constructActionChip(action, onFinish);
        }
        mActionContainer.addView(chip);
        mActionChips.add(chip);
    }
@@ -450,6 +509,27 @@ public class ClipboardOverlayView extends DraggableConstraintLayout {
        v.setVisibility(View.VISIBLE);
    }

    private View constructShelfActionChip(RemoteAction action, Runnable onFinish) {
        View chip = LayoutInflater.from(mContext).inflate(
                R.layout.shelf_action_chip, mActionContainer, false);
        ActionButtonViewBinder.INSTANCE.bind(chip, ActionButtonViewModel.Companion.withNextId(
                new ActionButtonAppearance(action.getIcon().loadDrawable(mContext),
                        action.getTitle(), action.getTitle()), new Function0<>() {
                    @Override
                    public Unit invoke() {
                        try {
                            action.getActionIntent().send();
                            onFinish.run();
                        } catch (PendingIntent.CanceledException e) {
                            Log.e(TAG, "Failed to send intent");
                        }
                        return null;
                    }
                }));

        return chip;
    }

    private OverlayActionChip constructActionChip(RemoteAction action, Runnable onFinish) {
        OverlayActionChip chip = (OverlayActionChip) LayoutInflater.from(mContext).inflate(
                R.layout.overlay_action_chip, mActionContainer, false);
+9 −2
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.clipboardoverlay.dagger;

import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;

import static com.android.systemui.Flags.screenshotShelfUi2;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import android.content.Context;
@@ -57,9 +59,14 @@ public interface ClipboardOverlayModule {
     */
    @Provides
    static ClipboardOverlayView provideClipboardOverlayView(@OverlayWindowContext Context context) {
        if (screenshotShelfUi2()) {
            return (ClipboardOverlayView) LayoutInflater.from(context).inflate(
                    R.layout.clipboard_overlay2, null);
        } else {
            return (ClipboardOverlayView) LayoutInflater.from(context).inflate(
                    R.layout.clipboard_overlay, null);
        }
    }

    @Qualifier
    @Documented