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

Commit acb1d81b authored by Miranda Kephart's avatar Miranda Kephart Committed by Matt Casey
Browse files

Switch to callback version of ScreenshotActionsProvider

Bug: 329659738
Test: manual
Flag: ACONFIG com.android.systemui.screenshot_shelf_ui DEVELOPMENT

Change-Id: I19a098248c8be5c6b768a8a2e9709ad87f131e62
Merged-In: I19a098248c8be5c6b768a8a2e9709ad87f131e62
parent 8a49392b
Loading
Loading
Loading
Loading
+37 −15
Original line number Original line Diff line number Diff line
@@ -26,34 +26,45 @@ import com.android.systemui.res.R
import javax.inject.Inject
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.
 * implementation.
 */
 */
interface ScreenshotActionsProvider {
interface ScreenshotActionsProvider {
    data class ScreenshotAction(
    data class ScreenshotAction(
        val icon: Drawable?,
        val icon: Drawable? = null,
        val text: String?,
        val text: String? = null,
        val overrideTransition: Boolean,
        val description: String,
        val overrideTransition: Boolean = false,
        val retrieveIntent: (Uri) -> Intent
        val retrieveIntent: (Uri) -> Intent
    )
    )


    fun getPreviewAction(context: Context, uri: Uri, user: UserHandle): Intent
    interface ScreenshotActionsCallback {
    fun getActions(context: Context, user: UserHandle): List<ScreenshotAction>
        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 {
    interface Factory {
    override fun getPreviewAction(context: Context, uri: Uri, user: UserHandle): Intent {
        fun create(
        return ActionIntentCreator.createEdit(uri, context)
            context: Context,
            user: UserHandle?,
            callback: ScreenshotActionsCallback
        ): ScreenshotActionsProvider
    }
}
}


    override fun getActions(
class DefaultScreenshotActionsProvider(
        context: Context,
    private val context: Context,
        user: UserHandle
    private val user: UserHandle?,
    ): List<ScreenshotActionsProvider.ScreenshotAction> {
    private val callback: ScreenshotActionsProvider.ScreenshotActionsCallback
) : ScreenshotActionsProvider {
    init {
        callback.setPreviewAction(true) { ActionIntentCreator.createEdit(it, context) }
        val editAction =
        val editAction =
            ScreenshotActionsProvider.ScreenshotAction(
            ScreenshotActionsProvider.ScreenshotAction(
                AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit),
                AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit),
                context.resources.getString(R.string.screenshot_edit_label),
                context.resources.getString(R.string.screenshot_edit_label),
                context.resources.getString(R.string.screenshot_edit_description),
                true
                true
            ) { uri ->
            ) { uri ->
                ActionIntentCreator.createEdit(uri, context)
                ActionIntentCreator.createEdit(uri, context)
@@ -62,10 +73,21 @@ class DefaultScreenshotActionsProvider @Inject constructor() : ScreenshotActions
            ScreenshotActionsProvider.ScreenshotAction(
            ScreenshotActionsProvider.ScreenshotAction(
                AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share),
                AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share),
                context.resources.getString(R.string.screenshot_share_label),
                context.resources.getString(R.string.screenshot_share_label),
                context.resources.getString(R.string.screenshot_share_description),
                false
                false
            ) { uri ->
            ) { uri ->
                ActionIntentCreator.createShare(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 −7
Original line number Original line 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.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
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_ANIM;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
@@ -237,6 +238,7 @@ public class ScreenshotController {
    private final WindowContext mContext;
    private final WindowContext mContext;
    private final FeatureFlags mFlags;
    private final FeatureFlags mFlags;
    private final ScreenshotViewProxy mViewProxy;
    private final ScreenshotViewProxy mViewProxy;
    private final ScreenshotActionsProvider.Factory mActionsProviderFactory;
    private final ScreenshotNotificationsController mNotificationsController;
    private final ScreenshotNotificationsController mNotificationsController;
    private final ScreenshotSmartActions mScreenshotSmartActions;
    private final ScreenshotSmartActions mScreenshotSmartActions;
    private final UiEventLogger mUiEventLogger;
    private final UiEventLogger mUiEventLogger;
@@ -271,6 +273,8 @@ public class ScreenshotController {
    private boolean mScreenshotTakenInPortrait;
    private boolean mScreenshotTakenInPortrait;
    private boolean mBlockAttach;
    private boolean mBlockAttach;


    private ScreenshotActionsProvider mActionsProvider;

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


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


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

        mCurrentRequestCallback = requestCallback;
        mCurrentRequestCallback = requestCallback;
        if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_FULLSCREEN) {
        if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_FULLSCREEN) {
            Rect bounds = getFullScreenRect();
            Rect bounds = getFullScreenRect();
@@ -496,7 +503,7 @@ public class ScreenshotController {
        return mDisplayId == Display.DEFAULT_DISPLAY || mShowUIOnExternalDisplay;
        return mDisplayId == Display.DEFAULT_DISPLAY || mShowUIOnExternalDisplay;
    }
    }


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


        mViewProxy.reset();
        mViewProxy.reset();


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

        if (mViewProxy.isAttachedToWindow()) {
        if (mViewProxy.isAttachedToWindow()) {
            // if we didn't already dismiss for another reason
            // if we didn't already dismiss for another reason
            if (!mViewProxy.isDismissing()) {
            if (!mViewProxy.isDismissing()) {
@@ -983,20 +995,16 @@ public class ScreenshotController {
                        @Override
                        @Override
                        public void onAnimationEnd(Animator animation) {
                        public void onAnimationEnd(Animator animation) {
                            super.onAnimationEnd(animation);
                            super.onAnimationEnd(animation);
                            doPostAnimation(imageData);
                            mViewProxy.setChipIntents(imageData);
                        }
                        }
                    });
                    });
                } else {
                } 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.
     * Sets up the action shade and its entrance animation, once we get the Quick Share action data.
     */
     */
+49 −16
Original line number Original line Diff line number Diff line
@@ -20,8 +20,10 @@ import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorListenerAdapter
import android.app.Notification
import android.app.Notification
import android.content.Context
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Bitmap
import android.graphics.Rect
import android.graphics.Rect
import android.net.Uri
import android.view.KeyEvent
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.LayoutInflater
import android.view.ScrollCaptureResponse
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_DISMISS
import com.android.systemui.screenshot.LogConfig.DEBUG_INPUT
import com.android.systemui.screenshot.LogConfig.DEBUG_INPUT
import com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW
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.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER
import com.android.systemui.screenshot.scroll.ScrollCaptureController
import com.android.systemui.screenshot.scroll.ScrollCaptureController
import com.android.systemui.screenshot.ui.ScreenshotAnimationController
import com.android.systemui.screenshot.ui.ScreenshotAnimationController
@@ -54,10 +57,9 @@ class ScreenshotShelfViewProxy
constructor(
constructor(
    private val logger: UiEventLogger,
    private val logger: UiEventLogger,
    private val viewModel: ScreenshotViewModel,
    private val viewModel: ScreenshotViewModel,
    private val staticActionsProvider: ScreenshotActionsProvider,
    @Assisted private val context: Context,
    @Assisted private val context: Context,
    @Assisted private val displayId: Int
    @Assisted private val displayId: Int
) : ScreenshotViewProxy {
) : ScreenshotViewProxy, ScreenshotActionsProvider.ScreenshotActionsCallback {
    override val view: ScreenshotShelfView =
    override val view: ScreenshotShelfView =
        LayoutInflater.from(context).inflate(R.layout.screenshot_shelf, null) as ScreenshotShelfView
        LayoutInflater.from(context).inflate(R.layout.screenshot_shelf, null) as ScreenshotShelfView
    override val screenshotPreview: View
    override val screenshotPreview: View
@@ -75,6 +77,8 @@ constructor(
    override var isPendingSharedTransition = false
    override var isPendingSharedTransition = false


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


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


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


    override fun setChipIntents(imageData: ScreenshotController.SavedImageData) {
    override fun setChipIntents(data: SavedImageData) {
        val staticActions =
        imageData = data
            staticActionsProvider.getActions(context, imageData.owner).map {
        runOnImageDataAcquired?.invoke(data)
                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 requestDismissal(event: ScreenshotEvent) {
    override fun requestDismissal(event: ScreenshotEvent) {
@@ -223,4 +219,41 @@ constructor(
    interface Factory : ScreenshotViewProxy.Factory {
    interface Factory : ScreenshotViewProxy.Factory {
        override fun getProxy(context: Context, displayId: Int): ScreenshotShelfViewProxy
        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
    }
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -94,8 +94,8 @@ public abstract class ScreenshotModule {
            ScreenshotSoundControllerImpl screenshotSoundProviderImpl);
            ScreenshotSoundControllerImpl screenshotSoundProviderImpl);


    @Binds
    @Binds
    abstract ScreenshotActionsProvider bindScreenshotActionsProvider(
    abstract ScreenshotActionsProvider.Factory bindScreenshotActionsProviderFactory(
            DefaultScreenshotActionsProvider defaultScreenshotActionsProvider);
            DefaultScreenshotActionsProvider.Factory defaultScreenshotActionsProviderFactory);


    @Provides
    @Provides
    @SysUISingleton
    @SysUISingleton
+1 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ object ActionButtonViewBinder {
        } else {
        } else {
            view.setOnClickListener(null)
            view.setOnClickListener(null)
        }
        }
        view.contentDescription = viewModel.description
        view.visibility = View.VISIBLE
        view.visibility = View.VISIBLE
        view.alpha = 1f
        view.alpha = 1f
    }
    }
Loading