Loading packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt +6 −3 Original line number Diff line number Diff line Loading @@ -87,7 +87,8 @@ constructor( AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit), context.resources.getString(R.string.screenshot_edit_label), context.resources.getString(R.string.screenshot_edit_description), ) ), showDuringEntrance = true, ) { debugLog(LogConfig.DEBUG_ACTIONS) { "Edit tapped" } uiEventLogger.log(SCREENSHOT_EDIT_TAPPED, 0, request.packageNameString) Loading @@ -105,7 +106,8 @@ constructor( AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share), context.resources.getString(R.string.screenshot_share_label), context.resources.getString(R.string.screenshot_share_description), ) ), showDuringEntrance = true, ) { debugLog(LogConfig.DEBUG_ACTIONS) { "Share tapped" } uiEventLogger.log(SCREENSHOT_SHARE_TAPPED, 0, request.packageNameString) Loading @@ -125,7 +127,8 @@ constructor( AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_scroll), context.resources.getString(R.string.screenshot_scroll_label), context.resources.getString(R.string.screenshot_scroll_label), ) ), showDuringEntrance = true, ) { onClick.run() } Loading packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt +10 −2 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.screenshot.scroll.ScrollCaptureController import com.android.systemui.screenshot.ui.ScreenshotAnimationController import com.android.systemui.screenshot.ui.ScreenshotShelfView import com.android.systemui.screenshot.ui.binder.ScreenshotShelfViewBinder import com.android.systemui.screenshot.ui.viewmodel.AnimationState import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedFactory Loading Loading @@ -119,12 +120,19 @@ constructor( override fun updateOrientation(insets: WindowInsets) {} override fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator { val entrance = animationController.getEntranceAnimation(screenRect, showFlash) entrance.doOnStart { thumbnailObserver.onEntranceStarted() } val entrance = animationController.getEntranceAnimation(screenRect, showFlash) { viewModel.setAnimationState(AnimationState.ENTRANCE_REVEAL) } entrance.doOnStart { thumbnailObserver.onEntranceStarted() viewModel.setAnimationState(AnimationState.ENTRANCE_STARTED) } entrance.doOnEnd { // reset the timeout when animation finishes callbacks?.onUserInteraction() thumbnailObserver.onEntranceComplete() viewModel.setAnimationState(AnimationState.ENTRANCE_COMPLETE) } return entrance } Loading packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotAnimationController.kt +19 −2 Original line number Diff line number Diff line Loading @@ -47,7 +47,11 @@ class ScreenshotAnimationController(private val view: ScreenshotShelfView) { view.requireViewById(R.id.screenshot_dismiss_button) ) fun getEntranceAnimation(bounds: Rect, showFlash: Boolean): Animator { fun getEntranceAnimation( bounds: Rect, showFlash: Boolean, onRevealMilestone: () -> Unit ): Animator { val entranceAnimation = AnimatorSet() val previewAnimator = getPreviewAnimator(bounds) Loading @@ -70,7 +74,19 @@ class ScreenshotAnimationController(private val view: ScreenshotShelfView) { entranceAnimation.doOnStart { screenshotPreview.visibility = View.INVISIBLE } } entranceAnimation.play(getActionsAnimator()).with(previewAnimator) val actionsAnimator = getActionsAnimator() entranceAnimation.play(actionsAnimator).with(previewAnimator) // This isn't actually animating anything but is basically a timer for the first 200ms of // the entrance animation. Using an animator here ensures that this is scaled if we change // animator duration scales. val revealMilestoneAnimator = ValueAnimator.ofFloat(0f).apply { duration = 0 startDelay = ACTION_REVEAL_DELAY_MS doOnEnd { onRevealMilestone() } } entranceAnimation.play(revealMilestoneAnimator).with(actionsAnimator) val fadeInAnimator = ValueAnimator.ofFloat(0f, 1f) fadeInAnimator.addUpdateListener { Loading Loading @@ -198,5 +214,6 @@ class ScreenshotAnimationController(private val view: ScreenshotShelfView) { private const val FLASH_OUT_DURATION_MS: Long = 217 private const val PREVIEW_X_ANIMATION_DURATION_MS: Long = 234 private const val PREVIEW_Y_ANIMATION_DURATION_MS: Long = 500 private const val ACTION_REVEAL_DELAY_MS: Long = 200 } } packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt +64 −38 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import com.android.systemui.res.R import com.android.systemui.screenshot.ScreenshotEvent import com.android.systemui.screenshot.ui.ScreenshotShelfView import com.android.systemui.screenshot.ui.SwipeGestureListener import com.android.systemui.screenshot.ui.viewmodel.ActionButtonViewModel import com.android.systemui.screenshot.ui.viewmodel.AnimationState import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel import com.android.systemui.util.children import kotlinx.coroutines.Dispatchers Loading Loading @@ -59,7 +61,6 @@ object ScreenshotShelfViewBinder { val previewBorder = view.requireViewById<View>(R.id.screenshot_preview_border) previewView.clipToOutline = true previewViewBlur.clipToOutline = true val actionsContainer: LinearLayout = view.requireViewById(R.id.screenshot_actions) val dismissButton = view.requireViewById<View>(R.id.screenshot_dismiss_button) dismissButton.visibility = if (viewModel.showDismissButton) View.VISIBLE else View.GONE dismissButton.setOnClickListener { Loading Loading @@ -90,12 +91,46 @@ object ScreenshotShelfViewBinder { } launch { viewModel.actions.collect { actions -> val visibleActions = actions.filter { it.visible } updateActions( actions, viewModel.animationState.value, view, layoutInflater ) } } launch { viewModel.animationState.collect { animationState -> updateActions( viewModel.actions.value, animationState, view, layoutInflater ) } } } } } } private fun updateActions( actions: List<ActionButtonViewModel>, animationState: AnimationState, view: ScreenshotShelfView, layoutInflater: LayoutInflater ) { val actionsContainer: LinearLayout = view.requireViewById(R.id.screenshot_actions) val visibleActions = actions.filter { it.visible && (animationState == AnimationState.ENTRANCE_COMPLETE || animationState == AnimationState.ENTRANCE_REVEAL || it.showDuringEntrance) } if (visibleActions.isNotEmpty()) { view .requireViewById<View>(R.id.actions_container_background) .visibility = View.VISIBLE view.requireViewById<View>(R.id.actions_container_background).visibility = View.VISIBLE } // Remove any buttons not in the new list, then do another pass to add Loading @@ -119,21 +154,12 @@ object ScreenshotShelfViewBinder { // Different ID. Removals have already happened so this must // mean that the new action must be inserted here. val actionButton = layoutInflater.inflate( R.layout.shelf_action_chip, actionsContainer, false ) layoutInflater.inflate(R.layout.shelf_action_chip, actionsContainer, false) actionsContainer.addView(actionButton, index) ActionButtonViewBinder.bind(actionButton, action) } } } } } } } } private fun setScreenshotBitmap(screenshotPreview: ImageView, bitmap: Bitmap) { screenshotPreview.setImageBitmap(bitmap) Loading packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt +9 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ data class ActionButtonViewModel( val appearance: ActionButtonAppearance, val id: Int, val visible: Boolean, val showDuringEntrance: Boolean, val onClicked: (() -> Unit)?, ) { companion object { Loading @@ -29,7 +30,14 @@ data class ActionButtonViewModel( fun withNextId( appearance: ActionButtonAppearance, showDuringEntrance: Boolean, onClicked: (() -> Unit)? ): ActionButtonViewModel = ActionButtonViewModel(appearance, getId(), true, onClicked) ): ActionButtonViewModel = ActionButtonViewModel(appearance, getId(), true, showDuringEntrance, onClicked) fun withNextId( appearance: ActionButtonAppearance, onClicked: (() -> Unit)? ): ActionButtonViewModel = withNextId(appearance, showDuringEntrance = true, onClicked) } } Loading
packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt +6 −3 Original line number Diff line number Diff line Loading @@ -87,7 +87,8 @@ constructor( AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit), context.resources.getString(R.string.screenshot_edit_label), context.resources.getString(R.string.screenshot_edit_description), ) ), showDuringEntrance = true, ) { debugLog(LogConfig.DEBUG_ACTIONS) { "Edit tapped" } uiEventLogger.log(SCREENSHOT_EDIT_TAPPED, 0, request.packageNameString) Loading @@ -105,7 +106,8 @@ constructor( AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share), context.resources.getString(R.string.screenshot_share_label), context.resources.getString(R.string.screenshot_share_description), ) ), showDuringEntrance = true, ) { debugLog(LogConfig.DEBUG_ACTIONS) { "Share tapped" } uiEventLogger.log(SCREENSHOT_SHARE_TAPPED, 0, request.packageNameString) Loading @@ -125,7 +127,8 @@ constructor( AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_scroll), context.resources.getString(R.string.screenshot_scroll_label), context.resources.getString(R.string.screenshot_scroll_label), ) ), showDuringEntrance = true, ) { onClick.run() } Loading
packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt +10 −2 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.screenshot.scroll.ScrollCaptureController import com.android.systemui.screenshot.ui.ScreenshotAnimationController import com.android.systemui.screenshot.ui.ScreenshotShelfView import com.android.systemui.screenshot.ui.binder.ScreenshotShelfViewBinder import com.android.systemui.screenshot.ui.viewmodel.AnimationState import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedFactory Loading Loading @@ -119,12 +120,19 @@ constructor( override fun updateOrientation(insets: WindowInsets) {} override fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator { val entrance = animationController.getEntranceAnimation(screenRect, showFlash) entrance.doOnStart { thumbnailObserver.onEntranceStarted() } val entrance = animationController.getEntranceAnimation(screenRect, showFlash) { viewModel.setAnimationState(AnimationState.ENTRANCE_REVEAL) } entrance.doOnStart { thumbnailObserver.onEntranceStarted() viewModel.setAnimationState(AnimationState.ENTRANCE_STARTED) } entrance.doOnEnd { // reset the timeout when animation finishes callbacks?.onUserInteraction() thumbnailObserver.onEntranceComplete() viewModel.setAnimationState(AnimationState.ENTRANCE_COMPLETE) } return entrance } Loading
packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotAnimationController.kt +19 −2 Original line number Diff line number Diff line Loading @@ -47,7 +47,11 @@ class ScreenshotAnimationController(private val view: ScreenshotShelfView) { view.requireViewById(R.id.screenshot_dismiss_button) ) fun getEntranceAnimation(bounds: Rect, showFlash: Boolean): Animator { fun getEntranceAnimation( bounds: Rect, showFlash: Boolean, onRevealMilestone: () -> Unit ): Animator { val entranceAnimation = AnimatorSet() val previewAnimator = getPreviewAnimator(bounds) Loading @@ -70,7 +74,19 @@ class ScreenshotAnimationController(private val view: ScreenshotShelfView) { entranceAnimation.doOnStart { screenshotPreview.visibility = View.INVISIBLE } } entranceAnimation.play(getActionsAnimator()).with(previewAnimator) val actionsAnimator = getActionsAnimator() entranceAnimation.play(actionsAnimator).with(previewAnimator) // This isn't actually animating anything but is basically a timer for the first 200ms of // the entrance animation. Using an animator here ensures that this is scaled if we change // animator duration scales. val revealMilestoneAnimator = ValueAnimator.ofFloat(0f).apply { duration = 0 startDelay = ACTION_REVEAL_DELAY_MS doOnEnd { onRevealMilestone() } } entranceAnimation.play(revealMilestoneAnimator).with(actionsAnimator) val fadeInAnimator = ValueAnimator.ofFloat(0f, 1f) fadeInAnimator.addUpdateListener { Loading Loading @@ -198,5 +214,6 @@ class ScreenshotAnimationController(private val view: ScreenshotShelfView) { private const val FLASH_OUT_DURATION_MS: Long = 217 private const val PREVIEW_X_ANIMATION_DURATION_MS: Long = 234 private const val PREVIEW_Y_ANIMATION_DURATION_MS: Long = 500 private const val ACTION_REVEAL_DELAY_MS: Long = 200 } }
packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt +64 −38 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import com.android.systemui.res.R import com.android.systemui.screenshot.ScreenshotEvent import com.android.systemui.screenshot.ui.ScreenshotShelfView import com.android.systemui.screenshot.ui.SwipeGestureListener import com.android.systemui.screenshot.ui.viewmodel.ActionButtonViewModel import com.android.systemui.screenshot.ui.viewmodel.AnimationState import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel import com.android.systemui.util.children import kotlinx.coroutines.Dispatchers Loading Loading @@ -59,7 +61,6 @@ object ScreenshotShelfViewBinder { val previewBorder = view.requireViewById<View>(R.id.screenshot_preview_border) previewView.clipToOutline = true previewViewBlur.clipToOutline = true val actionsContainer: LinearLayout = view.requireViewById(R.id.screenshot_actions) val dismissButton = view.requireViewById<View>(R.id.screenshot_dismiss_button) dismissButton.visibility = if (viewModel.showDismissButton) View.VISIBLE else View.GONE dismissButton.setOnClickListener { Loading Loading @@ -90,12 +91,46 @@ object ScreenshotShelfViewBinder { } launch { viewModel.actions.collect { actions -> val visibleActions = actions.filter { it.visible } updateActions( actions, viewModel.animationState.value, view, layoutInflater ) } } launch { viewModel.animationState.collect { animationState -> updateActions( viewModel.actions.value, animationState, view, layoutInflater ) } } } } } } private fun updateActions( actions: List<ActionButtonViewModel>, animationState: AnimationState, view: ScreenshotShelfView, layoutInflater: LayoutInflater ) { val actionsContainer: LinearLayout = view.requireViewById(R.id.screenshot_actions) val visibleActions = actions.filter { it.visible && (animationState == AnimationState.ENTRANCE_COMPLETE || animationState == AnimationState.ENTRANCE_REVEAL || it.showDuringEntrance) } if (visibleActions.isNotEmpty()) { view .requireViewById<View>(R.id.actions_container_background) .visibility = View.VISIBLE view.requireViewById<View>(R.id.actions_container_background).visibility = View.VISIBLE } // Remove any buttons not in the new list, then do another pass to add Loading @@ -119,21 +154,12 @@ object ScreenshotShelfViewBinder { // Different ID. Removals have already happened so this must // mean that the new action must be inserted here. val actionButton = layoutInflater.inflate( R.layout.shelf_action_chip, actionsContainer, false ) layoutInflater.inflate(R.layout.shelf_action_chip, actionsContainer, false) actionsContainer.addView(actionButton, index) ActionButtonViewBinder.bind(actionButton, action) } } } } } } } } private fun setScreenshotBitmap(screenshotPreview: ImageView, bitmap: Bitmap) { screenshotPreview.setImageBitmap(bitmap) Loading
packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt +9 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ data class ActionButtonViewModel( val appearance: ActionButtonAppearance, val id: Int, val visible: Boolean, val showDuringEntrance: Boolean, val onClicked: (() -> Unit)?, ) { companion object { Loading @@ -29,7 +30,14 @@ data class ActionButtonViewModel( fun withNextId( appearance: ActionButtonAppearance, showDuringEntrance: Boolean, onClicked: (() -> Unit)? ): ActionButtonViewModel = ActionButtonViewModel(appearance, getId(), true, onClicked) ): ActionButtonViewModel = ActionButtonViewModel(appearance, getId(), true, showDuringEntrance, onClicked) fun withNextId( appearance: ActionButtonAppearance, onClicked: (() -> Unit)? ): ActionButtonViewModel = withNextId(appearance, showDuringEntrance = true, onClicked) } }