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

Commit ec3d6001 authored by Miranda Kephart's avatar Miranda Kephart Committed by Automerger Merge Worker
Browse files

Merge "Implement minimized clipboard layout" into tm-qpr-dev am: 16bc6a5e am: 8a6e800c

parents b79472df 8a6e800c
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2023 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.
  -->
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
    android:shape="rectangle">
    <solid android:color="?androidprv:attr/colorAccentSecondary"/>
    <corners android:radius="10dp"/>
</shape>
+25 −0
Original line number Diff line number Diff line
<!--
  ~ Copyright (C) 2023 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.
  -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="48dp"
        android:height="48dp"
        android:viewportWidth="48"
        android:viewportHeight="48"
        android:tint="?attr/colorControlNormal">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M9,42Q7.7,42 6.85,41.15Q6,40.3 6,39V9Q6,7.7 6.85,6.85Q7.7,6 9,6H19.1Q19.45,4.25 20.825,3.125Q22.2,2 24,2Q25.8,2 27.175,3.125Q28.55,4.25 28.9,6H39Q40.3,6 41.15,6.85Q42,7.7 42,9V39Q42,40.3 41.15,41.15Q40.3,42 39,42ZM9,39H39Q39,39 39,39Q39,39 39,39V9Q39,9 39,9Q39,9 39,9H36V13.5H12V9H9Q9,9 9,9Q9,9 9,9V39Q9,39 9,39Q9,39 9,39ZM24,9Q24.85,9 25.425,8.425Q26,7.85 26,7Q26,6.15 25.425,5.575Q24.85,5 24,5Q23.15,5 22.575,5.575Q22,6.15 22,7Q22,7.85 22.575,8.425Q23.15,9 24,9Z"/>
</vector>
 No newline at end of file
+43 −4
Original line number Diff line number Diff line
@@ -125,6 +125,45 @@
            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"
@@ -132,10 +171,10 @@
        android:elevation="10dp"
        android:visibility="gone"
        android:alpha="0"
        app:layout_constraintStart_toEndOf="@id/clipboard_preview"
        app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
        app:layout_constraintTop_toTopOf="@id/clipboard_preview"
        app:layout_constraintBottom_toTopOf="@id/clipboard_preview"
        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"
+12 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.content.ClipDescription.CLASSIFICATION_COMPLETE;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ENTERED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_UPDATED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_TOAST_SHOWN;
import static com.android.systemui.flags.Flags.CLIPBOARD_MINIMIZED_LAYOUT;

import static com.google.android.setupcompat.util.WizardManagerHelper.SETTINGS_SECURE_USER_SETUP_COMPLETE;

@@ -35,6 +36,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;

import javax.inject.Inject;
import javax.inject.Provider;
@@ -57,6 +59,7 @@ public class ClipboardListener implements
    private final Provider<ClipboardOverlayController> mOverlayProvider;
    private final ClipboardToast mClipboardToast;
    private final ClipboardManager mClipboardManager;
    private final FeatureFlags mFeatureFlags;
    private final UiEventLogger mUiEventLogger;
    private ClipboardOverlay mClipboardOverlay;

@@ -65,11 +68,13 @@ public class ClipboardListener implements
            Provider<ClipboardOverlayController> clipboardOverlayControllerProvider,
            ClipboardToast clipboardToast,
            ClipboardManager clipboardManager,
            FeatureFlags featureFlags,
            UiEventLogger uiEventLogger) {
        mContext = context;
        mOverlayProvider = clipboardOverlayControllerProvider;
        mClipboardToast = clipboardToast;
        mClipboardManager = clipboardManager;
        mFeatureFlags = featureFlags;
        mUiEventLogger = uiEventLogger;
    }

@@ -107,7 +112,11 @@ public class ClipboardListener implements
        } else {
            mUiEventLogger.log(CLIPBOARD_OVERLAY_UPDATED, 0, clipSource);
        }
        if (mFeatureFlags.isEnabled(CLIPBOARD_MINIMIZED_LAYOUT)) {
            mClipboardOverlay.setClipData(clipData, clipSource);
        } else {
            mClipboardOverlay.setClipDataLegacy(clipData, clipSource);
        }
        mClipboardOverlay.setOnSessionCompleteListener(() -> {
            // Session is complete, free memory until it's needed again.
            mClipboardOverlay = null;
@@ -150,6 +159,8 @@ public class ClipboardListener implements
    }

    interface ClipboardOverlay {
        void setClipDataLegacy(ClipData clipData, String clipSource);

        void setClipData(ClipData clipData, String clipSource);

        void setOnSessionCompleteListener(Runnable runnable);
+101 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.
 */
package com.android.systemui.clipboardoverlay

import android.content.ClipData
import android.content.ClipDescription.EXTRA_IS_SENSITIVE
import android.content.Context
import android.graphics.Bitmap
import android.text.TextUtils
import android.util.Log
import android.util.Size
import com.android.systemui.R
import java.io.IOException

data class ClipboardModel(
    val clipData: ClipData?,
    val source: String,
    val type: Type = Type.OTHER,
    val item: ClipData.Item? = null,
    val isSensitive: Boolean = false,
    val isRemote: Boolean = false,
) {
    private var _bitmap: Bitmap? = null

    fun dataMatches(other: ClipboardModel?): Boolean {
        if (other == null) {
            return false
        }
        return source == other.source &&
            type == other.type &&
            item?.text == other.item?.text &&
            item?.uri == other.item?.uri &&
            isSensitive == other.isSensitive
    }

    fun loadThumbnail(context: Context): Bitmap? {
        if (_bitmap == null && type == Type.IMAGE && item?.uri != null) {
            try {
                val size = context.resources.getDimensionPixelSize(R.dimen.overlay_x_scale)
                _bitmap =
                    context.contentResolver.loadThumbnail(item.uri, Size(size, size * 4), null)
            } catch (e: IOException) {
                Log.e(TAG, "Thumbnail loading failed!", e)
            }
        }
        return _bitmap
    }

    internal companion object {
        private val TAG: String = "ClipboardModel"

        @JvmStatic
        fun fromClipData(
            context: Context,
            utils: ClipboardOverlayUtils,
            clipData: ClipData?,
            source: String
        ): ClipboardModel {
            if (clipData == null || clipData.itemCount == 0) {
                return ClipboardModel(clipData, source)
            }
            val sensitive = clipData.description?.extras?.getBoolean(EXTRA_IS_SENSITIVE) ?: false
            val item = clipData.getItemAt(0)!!
            val type = getType(context, item)
            val remote = utils.isRemoteCopy(context, clipData, source)
            return ClipboardModel(clipData, source, type, item, sensitive, remote)
        }

        private fun getType(context: Context, item: ClipData.Item): Type {
            return if (!TextUtils.isEmpty(item.text)) {
                Type.TEXT
            } else if (
                item.uri != null &&
                    context.contentResolver.getType(item.uri)?.startsWith("image") == true
            ) {
                Type.IMAGE
            } else {
                Type.OTHER
            }
        }
    }

    enum class Type {
        TEXT,
        IMAGE,
        OTHER
    }
}
Loading