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

Commit 2483fb08 authored by Matt Casey's avatar Matt Casey Committed by Android (Google) Code Review
Browse files

Merge changes Ic3d9c27a,I84314ce9,I19a09824 into 24D1-dev

* changes:
  Move screenshot thumbnail above actions
  Remove all usages of SCREENSHOT_METADATA flag
  Switch to callback version of ScreenshotActionsProvider
parents 1ca93825 03f9cc3e
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@
        android:elevation="4dp"
        android:background="@drawable/action_chip_container_background"
        android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
        android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
        android:layout_marginBottom="@dimen/screenshot_shelf_vertical_margin"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/actions_container"
        app:layout_constraintEnd_toEndOf="@+id/actions_container"
@@ -38,14 +38,14 @@
        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:paddingHorizontal="@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/screenshot_preview_border"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="@id/actions_container_background">
        <LinearLayout
@@ -65,16 +65,16 @@
        android:id="@+id/screenshot_preview_border"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
        android:layout_marginTop="@dimen/overlay_border_width_neg"
        android:layout_marginEnd="@dimen/overlay_border_width_neg"
        android:layout_marginBottom="14dp"
        android:layout_marginBottom="@dimen/screenshot_shelf_vertical_margin"
        android:elevation="8dp"
        android:background="@drawable/overlay_border"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/screenshot_preview"
        app:layout_constraintEnd_toEndOf="@id/screenshot_preview"
        app:layout_constraintBottom_toBottomOf="parent"/>
        app:layout_constraintBottom_toTopOf="@id/actions_container"/>
    <ImageView
        android:id="@+id/screenshot_preview"
        android:layout_width="@dimen/overlay_x_scale"
+1 −0
Original line number Diff line number Diff line
@@ -448,6 +448,7 @@
    <dimen name="overlay_action_container_padding_end">8dp</dimen>
    <dimen name="overlay_dismiss_button_tappable_size">48dp</dimen>
    <dimen name="overlay_dismiss_button_margin">8dp</dimen>
    <dimen name="screenshot_shelf_vertical_margin">8dp</dimen>
    <!-- must be kept aligned with overlay_border_width_neg, below;
         overlay_border_width = overlay_border_width_neg * -1 -->
    <dimen name="overlay_border_width">4dp</dimen>
+37 −15
Original line number Diff line number Diff line
@@ -26,34 +26,45 @@ import com.android.systemui.res.R
import javax.inject.Inject

/**
 * Provides static actions for screenshots. This class can be overridden by a vendor-specific SysUI
 * Provides actions for screenshots. This class can be overridden by a vendor-specific SysUI
 * implementation.
 */
interface ScreenshotActionsProvider {
    data class ScreenshotAction(
        val icon: Drawable?,
        val text: String?,
        val overrideTransition: Boolean,
        val icon: Drawable? = null,
        val text: String? = null,
        val description: String,
        val overrideTransition: Boolean = false,
        val retrieveIntent: (Uri) -> Intent
    )

    fun getPreviewAction(context: Context, uri: Uri, user: UserHandle): Intent
    fun getActions(context: Context, user: UserHandle): List<ScreenshotAction>
    interface ScreenshotActionsCallback {
        fun setPreviewAction(overrideTransition: Boolean = false, retrieveIntent: (Uri) -> Intent)
        fun addAction(action: ScreenshotAction) = addActions(listOf(action))
        fun addActions(actions: List<ScreenshotAction>)
    }

class DefaultScreenshotActionsProvider @Inject constructor() : ScreenshotActionsProvider {
    override fun getPreviewAction(context: Context, uri: Uri, user: UserHandle): Intent {
        return ActionIntentCreator.createEdit(uri, context)
    interface Factory {
        fun create(
            context: Context,
            user: UserHandle?,
            callback: ScreenshotActionsCallback
        ): ScreenshotActionsProvider
    }
}

    override fun getActions(
        context: Context,
        user: UserHandle
    ): List<ScreenshotActionsProvider.ScreenshotAction> {
class DefaultScreenshotActionsProvider(
    private val context: Context,
    private val user: UserHandle?,
    private val callback: ScreenshotActionsProvider.ScreenshotActionsCallback
) : ScreenshotActionsProvider {
    init {
        callback.setPreviewAction(true) { ActionIntentCreator.createEdit(it, context) }
        val editAction =
            ScreenshotActionsProvider.ScreenshotAction(
                AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit),
                context.resources.getString(R.string.screenshot_edit_label),
                context.resources.getString(R.string.screenshot_edit_description),
                true
            ) { uri ->
                ActionIntentCreator.createEdit(uri, context)
@@ -62,10 +73,21 @@ class DefaultScreenshotActionsProvider @Inject constructor() : ScreenshotActions
            ScreenshotActionsProvider.ScreenshotAction(
                AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share),
                context.resources.getString(R.string.screenshot_share_label),
                context.resources.getString(R.string.screenshot_share_description),
                false
            ) { uri ->
                ActionIntentCreator.createShare(uri)
            }
        return listOf(editAction, shareAction)
        callback.addActions(listOf(editAction, shareAction))
    }

    class Factory @Inject constructor() : ScreenshotActionsProvider.Factory {
        override fun create(
            context: Context,
            user: UserHandle?,
            callback: ScreenshotActionsProvider.ScreenshotActionsCallback
        ): ScreenshotActionsProvider {
            return DefaultScreenshotActionsProvider(context, user, callback)
        }
    }
}
+15 −19
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.screenshot;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;

import static com.android.systemui.Flags.screenshotShelfUi;
import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
@@ -40,7 +41,6 @@ import android.app.ActivityOptions;
import android.app.ExitTransitionCoordinator;
import android.app.ICompatCameraControlCallback;
import android.app.Notification;
import android.app.assist.AssistContent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -84,7 +84,6 @@ import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.clipboardoverlay.ClipboardOverlayController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.res.R;
import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback;
import com.android.systemui.screenshot.scroll.LongScreenshotActivity;
@@ -237,6 +236,7 @@ public class ScreenshotController {
    private final WindowContext mContext;
    private final FeatureFlags mFlags;
    private final ScreenshotViewProxy mViewProxy;
    private final ScreenshotActionsProvider.Factory mActionsProviderFactory;
    private final ScreenshotNotificationsController mNotificationsController;
    private final ScreenshotSmartActions mScreenshotSmartActions;
    private final UiEventLogger mUiEventLogger;
@@ -271,6 +271,8 @@ public class ScreenshotController {
    private boolean mScreenshotTakenInPortrait;
    private boolean mBlockAttach;

    private ScreenshotActionsProvider mActionsProvider;

    private Animator mScreenshotAnimation;
    private RequestCallback mCurrentRequestCallback;
    private String mPackageName = "";
@@ -298,6 +300,7 @@ public class ScreenshotController {
            Context context,
            FeatureFlags flags,
            ScreenshotViewProxy.Factory viewProxyFactory,
            ScreenshotActionsProvider.Factory actionsProviderFactory,
            ScreenshotSmartActions screenshotSmartActions,
            ScreenshotNotificationsController.Factory screenshotNotificationsControllerFactory,
            ScrollCaptureClient scrollCaptureClient,
@@ -349,6 +352,7 @@ public class ScreenshotController {
        mAssistContentRequester = assistContentRequester;

        mViewProxy = viewProxyFactory.getProxy(mContext, mDisplayId);
        mActionsProviderFactory = actionsProviderFactory;

        mScreenshotHandler.setOnTimeoutRunnable(() -> {
            if (DEBUG_UI) {
@@ -393,6 +397,7 @@ public class ScreenshotController {
    void handleScreenshot(ScreenshotData screenshot, Consumer<Uri> finisher,
            RequestCallback requestCallback) {
        Assert.isMainThread();

        mCurrentRequestCallback = requestCallback;
        if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_FULLSCREEN) {
            Rect bounds = getFullScreenRect();
@@ -435,16 +440,6 @@ public class ScreenshotController {

        prepareViewForNewScreenshot(screenshot, oldPackageName);

        if (mFlags.isEnabled(Flags.SCREENSHOT_METADATA) && screenshot.getTaskId() >= 0) {
            mAssistContentRequester.requestAssistContent(screenshot.getTaskId(),
                    new AssistContentRequester.Callback() {
                        @Override
                        public void onAssistContentAvailable(AssistContent assistContent) {
                            screenshot.setContextUrl(assistContent.getWebUri());
                        }
                    });
        }

        if (!shouldShowUi()) {
            saveScreenshotInWorkerThread(
                    screenshot.getUserHandle(), finisher, this::logSuccessOnActionsReady,
@@ -496,7 +491,7 @@ public class ScreenshotController {
        return mDisplayId == Display.DEFAULT_DISPLAY || mShowUIOnExternalDisplay;
    }

    void prepareViewForNewScreenshot(ScreenshotData screenshot, String oldPackageName) {
    void prepareViewForNewScreenshot(@NonNull ScreenshotData screenshot, String oldPackageName) {
        withWindowAttached(() -> {
            if (mUserManager.isManagedProfile(screenshot.getUserHandle().getIdentifier())) {
                mViewProxy.announceForAccessibility(mContext.getResources().getString(
@@ -509,6 +504,11 @@ public class ScreenshotController {

        mViewProxy.reset();

        if (screenshotShelfUi()) {
            mActionsProvider = mActionsProviderFactory.create(mContext, screenshot.getUserHandle(),
                    ((ScreenshotActionsProvider.ScreenshotActionsCallback) mViewProxy));
        }

        if (mViewProxy.isAttachedToWindow()) {
            // if we didn't already dismiss for another reason
            if (!mViewProxy.isDismissing()) {
@@ -983,20 +983,16 @@ public class ScreenshotController {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            super.onAnimationEnd(animation);
                            doPostAnimation(imageData);
                            mViewProxy.setChipIntents(imageData);
                        }
                    });
                } else {
                    doPostAnimation(imageData);
                    mViewProxy.setChipIntents(imageData);
                }
            });
        }
    }

    private void doPostAnimation(ScreenshotController.SavedImageData imageData) {
        mViewProxy.setChipIntents(imageData);
    }

    /**
     * Sets up the action shade and its entrance animation, once we get the Quick Share action data.
     */
+49 −16
Original line number Diff line number Diff line
@@ -20,8 +20,10 @@ import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.app.Notification
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Rect
import android.net.Uri
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.ScrollCaptureResponse
@@ -37,6 +39,7 @@ import com.android.systemui.screenshot.LogConfig.DEBUG_ACTIONS
import com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS
import com.android.systemui.screenshot.LogConfig.DEBUG_INPUT
import com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW
import com.android.systemui.screenshot.ScreenshotController.SavedImageData
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER
import com.android.systemui.screenshot.scroll.ScrollCaptureController
import com.android.systemui.screenshot.ui.ScreenshotAnimationController
@@ -54,10 +57,9 @@ class ScreenshotShelfViewProxy
constructor(
    private val logger: UiEventLogger,
    private val viewModel: ScreenshotViewModel,
    private val staticActionsProvider: ScreenshotActionsProvider,
    @Assisted private val context: Context,
    @Assisted private val displayId: Int
) : ScreenshotViewProxy {
) : ScreenshotViewProxy, ScreenshotActionsProvider.ScreenshotActionsCallback {
    override val view: ScreenshotShelfView =
        LayoutInflater.from(context).inflate(R.layout.screenshot_shelf, null) as ScreenshotShelfView
    override val screenshotPreview: View
@@ -75,6 +77,8 @@ constructor(
    override var isPendingSharedTransition = false

    private val animationController = ScreenshotAnimationController(view)
    private var imageData: SavedImageData? = null
    private var runOnImageDataAcquired: ((SavedImageData) -> Unit)? = null

    init {
        ScreenshotShelfViewBinder.bind(view, viewModel, LayoutInflater.from(context))
@@ -87,8 +91,9 @@ constructor(
    override fun reset() {
        animationController.cancel()
        isPendingSharedTransition = false
        viewModel.setScreenshotBitmap(null)
        viewModel.setActions(listOf())
        imageData = null
        viewModel.reset()
        runOnImageDataAcquired = null
    }
    override fun updateInsets(insets: WindowInsets) {}
    override fun updateOrientation(insets: WindowInsets) {}
@@ -99,18 +104,9 @@ constructor(

    override fun addQuickShareChip(quickShareAction: Notification.Action) {}

    override fun setChipIntents(imageData: ScreenshotController.SavedImageData) {
        val staticActions =
            staticActionsProvider.getActions(context, imageData.owner).map {
                ActionButtonViewModel(it.icon, it.text) {
                    val intent = it.retrieveIntent(imageData.uri)
                    debugLog(DEBUG_ACTIONS) { "Action tapped: $intent" }
                    isPendingSharedTransition = true
                    callbacks?.onAction(intent, imageData.owner, it.overrideTransition)
                }
            }

        viewModel.setActions(staticActions)
    override fun setChipIntents(data: SavedImageData) {
        imageData = data
        runOnImageDataAcquired?.invoke(data)
    }

    override fun requestDismissal(event: ScreenshotEvent) {
@@ -223,4 +219,41 @@ constructor(
    interface Factory : ScreenshotViewProxy.Factory {
        override fun getProxy(context: Context, displayId: Int): ScreenshotShelfViewProxy
    }

    override fun setPreviewAction(overrideTransition: Boolean, retrieveIntent: (Uri) -> Intent) {
        viewModel.setPreviewAction {
            imageData?.let {
                val intent = retrieveIntent(it.uri)
                debugLog(DEBUG_ACTIONS) { "Preview tapped: $intent" }
                isPendingSharedTransition = true
                callbacks?.onAction(intent, it.owner, overrideTransition)
            }
        }
    }

    override fun addActions(actions: List<ScreenshotActionsProvider.ScreenshotAction>) {
        viewModel.addActions(
            actions.map { action ->
                ActionButtonViewModel(action.icon, action.text, action.description) {
                    val actionRunnable =
                        getActionRunnable(action.retrieveIntent, action.overrideTransition)
                    imageData?.let { actionRunnable(it) }
                        ?: run { runOnImageDataAcquired = actionRunnable }
                }
            }
        )
    }

    private fun getActionRunnable(
        retrieveIntent: (Uri) -> Intent,
        overrideTransition: Boolean
    ): (SavedImageData) -> Unit {
        val onClick: (SavedImageData) -> Unit = {
            val intent = retrieveIntent(it.uri)
            debugLog(DEBUG_ACTIONS) { "Action tapped: $intent" }
            isPendingSharedTransition = true
            callbacks!!.onAction(intent, it.owner, overrideTransition)
        }
        return onClick
    }
}
Loading