Switch to callback version of ScreenshotActionsProvider
Bug: 329659738
Test: manual
Flag: ACONFIG com.android.systemui.screenshot_shelf_ui DEVELOPMENT
Change-Id: I19a098248c8be5c6b768a8a2e9709ad87f131e62
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
index abdbd68..97acccd 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
@@ -26,34 +26,45 @@
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>
-}
-
-class DefaultScreenshotActionsProvider @Inject constructor() : ScreenshotActionsProvider {
- override fun getPreviewAction(context: Context, uri: Uri, user: UserHandle): Intent {
- return ActionIntentCreator.createEdit(uri, context)
+ interface ScreenshotActionsCallback {
+ fun setPreviewAction(overrideTransition: Boolean = false, retrieveIntent: (Uri) -> Intent)
+ fun addAction(action: ScreenshotAction) = addActions(listOf(action))
+ fun addActions(actions: List<ScreenshotAction>)
}
- override fun getActions(
- context: Context,
- user: UserHandle
- ): List<ScreenshotActionsProvider.ScreenshotAction> {
+ interface Factory {
+ fun create(
+ context: Context,
+ user: UserHandle?,
+ callback: ScreenshotActionsCallback
+ ): ScreenshotActionsProvider
+ }
+}
+
+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 @@
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)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index c8e13bb..b796a20 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -19,6 +19,7 @@
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;
@@ -237,6 +238,7 @@
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 +273,8 @@
private boolean mScreenshotTakenInPortrait;
private boolean mBlockAttach;
+ private ScreenshotActionsProvider mActionsProvider;
+
private Animator mScreenshotAnimation;
private RequestCallback mCurrentRequestCallback;
private String mPackageName = "";
@@ -298,6 +302,7 @@
Context context,
FeatureFlags flags,
ScreenshotViewProxy.Factory viewProxyFactory,
+ ScreenshotActionsProvider.Factory actionsProviderFactory,
ScreenshotSmartActions screenshotSmartActions,
ScreenshotNotificationsController.Factory screenshotNotificationsControllerFactory,
ScrollCaptureClient scrollCaptureClient,
@@ -349,6 +354,7 @@
mAssistContentRequester = assistContentRequester;
mViewProxy = viewProxyFactory.getProxy(mContext, mDisplayId);
+ mActionsProviderFactory = actionsProviderFactory;
mScreenshotHandler.setOnTimeoutRunnable(() -> {
if (DEBUG_UI) {
@@ -393,6 +399,7 @@
void handleScreenshot(ScreenshotData screenshot, Consumer<Uri> finisher,
RequestCallback requestCallback) {
Assert.isMainThread();
+
mCurrentRequestCallback = requestCallback;
if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_FULLSCREEN) {
Rect bounds = getFullScreenRect();
@@ -496,7 +503,7 @@
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 +516,11 @@
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 +995,16 @@
@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.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
index 9354fd2..88bca95 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
@@ -20,8 +20,10 @@
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_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 @@
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 @@
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 @@
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 @@
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 @@
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
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java b/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
index 9118ee1..2ce6d83 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
@@ -94,8 +94,8 @@
ScreenshotSoundControllerImpl screenshotSoundProviderImpl);
@Binds
- abstract ScreenshotActionsProvider bindScreenshotActionsProvider(
- DefaultScreenshotActionsProvider defaultScreenshotActionsProvider);
+ abstract ScreenshotActionsProvider.Factory bindScreenshotActionsProviderFactory(
+ DefaultScreenshotActionsProvider.Factory defaultScreenshotActionsProviderFactory);
@Provides
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
index a5825b5..c7fe3f6 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
@@ -36,6 +36,7 @@
} else {
view.setOnClickListener(null)
}
+ view.contentDescription = viewModel.description
view.visibility = View.VISIBLE
view.alpha = 1f
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
index 3bcd52c..d878200 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
@@ -59,6 +59,11 @@
}
}
launch {
+ viewModel.previewAction.collect { onClick ->
+ previewView.setOnClickListener { onClick?.run() }
+ }
+ }
+ launch {
viewModel.actions.collect { actions ->
if (actions.isNotEmpty()) {
view
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
index 6ee9705..05bfed1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
@@ -20,6 +20,7 @@
data class ActionButtonViewModel(
val icon: Drawable?,
- val name: String?,
+ val name: CharSequence?,
+ val description: CharSequence,
val onClicked: (() -> Unit)?
)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
index 3a652d9..dc61d1e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
@@ -24,6 +24,8 @@
class ScreenshotViewModel(private val accessibilityManager: AccessibilityManager) {
private val _preview = MutableStateFlow<Bitmap?>(null)
val preview: StateFlow<Bitmap?> = _preview
+ private val _previewAction = MutableStateFlow<Runnable?>(null)
+ val previewAction: StateFlow<Runnable?> = _previewAction
private val _actions = MutableStateFlow(emptyList<ActionButtonViewModel>())
val actions: StateFlow<List<ActionButtonViewModel>> = _actions
val showDismissButton: Boolean
@@ -33,7 +35,19 @@
_preview.value = bitmap
}
- fun setActions(actions: List<ActionButtonViewModel>) {
- _actions.value = actions
+ fun setPreviewAction(runnable: Runnable) {
+ _previewAction.value = runnable
+ }
+
+ fun addActions(actions: List<ActionButtonViewModel>) {
+ val actionList = _actions.value.toMutableList()
+ actionList.addAll(actions)
+ _actions.value = actionList
+ }
+
+ fun reset() {
+ _preview.value = null
+ _previewAction.value = null
+ _actions.value = listOf()
}
}