Files
Lawnchair/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
T
Jagrut Desai 2e8ca87c21 Taskbar in Desktop Windowing Mode
Test: presubmit
Bug: 330146462
Flag: NONE
Change-Id: Ib33f90704c3010df6a52e2a1c420960b11dbd0d4
2024-05-01 09:29:24 -07:00

163 lines
6.8 KiB
Kotlin

/*
* 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.launcher3.taskbar
import android.animation.AnimatorSet
import android.annotation.SuppressLint
import android.view.View
import androidx.annotation.VisibleForTesting
import androidx.core.animation.doOnEnd
import com.android.app.animation.Interpolators
import com.android.launcher3.LauncherPrefs
import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING_IN_DESKTOP_MODE
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_DIVIDER_MENU_CLOSE
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_DIVIDER_MENU_OPEN
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_PINNED
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_UNPINNED
import com.android.launcher3.taskbar.TaskbarDividerPopupView.Companion.createAndPopulate
import java.io.PrintWriter
/** Controls taskbar pinning through a popup view. */
class TaskbarPinningController(
private val context: TaskbarActivityContext,
private val isInDesktopModeProvider: () -> Boolean,
) : TaskbarControllers.LoggableTaskbarController {
private lateinit var controllers: TaskbarControllers
private lateinit var taskbarSharedState: TaskbarSharedState
private lateinit var launcherPrefs: LauncherPrefs
private val statsLogManager = context.statsLogManager
@VisibleForTesting var isAnimatingTaskbarPinning = false
@VisibleForTesting lateinit var onCloseCallback: (preferenceChanged: Boolean) -> Unit
@SuppressLint("VisibleForTests")
fun init(taskbarControllers: TaskbarControllers, sharedState: TaskbarSharedState) {
controllers = taskbarControllers
taskbarSharedState = sharedState
launcherPrefs = context.launcherPrefs
onCloseCallback =
fun(didPreferenceChange: Boolean) {
statsLogManager.logger().log(LAUNCHER_TASKBAR_DIVIDER_MENU_CLOSE)
context.dragLayer.post { context.onPopupVisibilityChanged(false) }
if (!didPreferenceChange) {
return
}
val shouldPinTaskbar =
if (isInDesktopModeProvider()) {
!launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE)
} else {
!launcherPrefs.get(TASKBAR_PINNING)
}
val animateToValue =
if (shouldPinTaskbar) {
statsLogManager.logger().log(LAUNCHER_TASKBAR_PINNED)
PINNING_PERSISTENT
} else {
statsLogManager.logger().log(LAUNCHER_TASKBAR_UNPINNED)
PINNING_TRANSIENT
}
taskbarSharedState.taskbarWasPinned = animateToValue == PINNING_TRANSIENT
animateTaskbarPinning(animateToValue)
}
}
fun showPinningView(view: View) {
context.isTaskbarWindowFullscreen = true
view.post {
val popupView = getPopupView(view)
popupView.requestFocus()
popupView.onCloseCallback = onCloseCallback
context.onPopupVisibilityChanged(true)
popupView.show()
statsLogManager.logger().log(LAUNCHER_TASKBAR_DIVIDER_MENU_OPEN)
}
}
@VisibleForTesting
fun getPopupView(view: View): TaskbarDividerPopupView<*> {
return createAndPopulate(view, context)
}
@VisibleForTesting
fun animateTaskbarPinning(animateToValue: Float) {
val taskbarViewController = controllers.taskbarViewController
val animatorSet =
getAnimatorSetForTaskbarPinningAnimation(animateToValue).apply {
doOnEnd { recreateTaskbarAndUpdatePinningValue() }
duration = PINNING_ANIMATION_DURATION
}
controllers.taskbarOverlayController.hideWindow()
updateIsAnimatingTaskbarPinningAndNotifyTaskbarDragLayer(true)
taskbarViewController.animateAwayNotificationDotsDuringTaskbarPinningAnimation()
animatorSet.start()
}
@VisibleForTesting
fun getAnimatorSetForTaskbarPinningAnimation(animateToValue: Float): AnimatorSet {
val animatorSet = AnimatorSet()
val taskbarViewController = controllers.taskbarViewController
val dragLayerController = controllers.taskbarDragLayerController
animatorSet.playTogether(
dragLayerController.taskbarBackgroundProgress.animateToValue(animateToValue),
taskbarViewController.taskbarIconTranslationYForPinning.animateToValue(animateToValue),
taskbarViewController.taskbarIconScaleForPinning.animateToValue(animateToValue),
taskbarViewController.taskbarIconTranslationXForPinning.animateToValue(animateToValue)
)
animatorSet.interpolator = Interpolators.EMPHASIZED
return animatorSet
}
private fun updateIsAnimatingTaskbarPinningAndNotifyTaskbarDragLayer(isAnimating: Boolean) {
isAnimatingTaskbarPinning = isAnimating
context.dragLayer.setAnimatingTaskbarPinning(isAnimating)
}
@VisibleForTesting
fun recreateTaskbarAndUpdatePinningValue() {
updateIsAnimatingTaskbarPinningAndNotifyTaskbarDragLayer(false)
if (isInDesktopModeProvider()) {
launcherPrefs.put(
TASKBAR_PINNING_IN_DESKTOP_MODE,
!launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE)
)
} else {
launcherPrefs.put(TASKBAR_PINNING, !launcherPrefs.get(TASKBAR_PINNING))
}
}
override fun dumpLogs(prefix: String, pw: PrintWriter) {
pw.println(prefix + "TaskbarPinningController:")
pw.println("$prefix\tisAnimatingTaskbarPinning=$isAnimatingTaskbarPinning")
pw.println("$prefix\tTASKBAR_PINNING shared pref =" + launcherPrefs.get(TASKBAR_PINNING))
pw.println(
"$prefix\tTASKBAR_PINNING_IN_DESKTOP_MODE shared pref in desktop mode =" +
launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE)
)
}
companion object {
const val PINNING_PERSISTENT = 1f
const val PINNING_TRANSIENT = 0f
const val PINNING_ANIMATION_DURATION = 600L
}
}