1d7ac8b8a7
Bug: 375661139 Test: confirmed with design team Flag: EXEMPT bugfix Change-Id: I0f9cce376d47918e69a65ed288f10143930ee3be
144 lines
5.7 KiB
Kotlin
144 lines
5.7 KiB
Kotlin
/*
|
|
* Copyright (C) 2024 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.customization
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.content.Context
|
|
import android.content.res.ColorStateList
|
|
import android.graphics.Color.TRANSPARENT
|
|
import android.util.AttributeSet
|
|
import android.view.MotionEvent
|
|
import android.view.View
|
|
import android.view.ViewConfiguration
|
|
import androidx.annotation.DimenRes
|
|
import androidx.annotation.DrawableRes
|
|
import com.android.launcher3.R
|
|
import com.android.launcher3.Utilities.dpToPx
|
|
import com.android.launcher3.config.FeatureFlags.enableTaskbarPinning
|
|
import com.android.launcher3.taskbar.TaskbarActivityContext
|
|
import com.android.launcher3.taskbar.TaskbarViewCallbacks
|
|
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
|
|
import com.android.launcher3.views.ActivityContext
|
|
import com.android.launcher3.views.IconButtonView
|
|
import com.android.quickstep.DeviceConfigWrapper
|
|
import com.android.quickstep.util.ContextualSearchStateManager
|
|
|
|
/** Taskbar all apps button container for customizable taskbar. */
|
|
class TaskbarAllAppsButtonContainer
|
|
@JvmOverloads
|
|
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
|
|
IconButtonView(context, attrs), TaskbarContainer {
|
|
|
|
private val activityContext: TaskbarActivityContext = ActivityContext.lookupContext(context)
|
|
private var allAppsTouchTriggered = false
|
|
private var allAppsTouchRunnable: Runnable? = null
|
|
private var allAppsButtonTouchDelayMs: Long = ViewConfiguration.getLongPressTimeout().toLong()
|
|
private lateinit var taskbarViewCallbacks: TaskbarViewCallbacks
|
|
|
|
override val spaceNeeded: Int
|
|
get() {
|
|
return dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconSize.size.toFloat())
|
|
}
|
|
|
|
init {
|
|
contentDescription = context.getString(R.string.all_apps_button_label)
|
|
setUpIcon()
|
|
}
|
|
|
|
@SuppressLint("UseCompatLoadingForDrawables", "ResourceAsColor")
|
|
private fun setUpIcon() {
|
|
val drawable =
|
|
resources.getDrawable(
|
|
getAllAppsButton(activityContext.taskbarFeatureEvaluator.isTransient)
|
|
)
|
|
backgroundTintList = ColorStateList.valueOf(TRANSPARENT)
|
|
setIconDrawable(drawable)
|
|
setForegroundTint(activityContext.getColor(R.color.all_apps_button_color))
|
|
}
|
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
fun setUpCallbacks(callbacks: TaskbarViewCallbacks) {
|
|
taskbarViewCallbacks = callbacks
|
|
setOnClickListener(this::onAllAppsButtonClick)
|
|
setOnLongClickListener(this::onAllAppsButtonLongClick)
|
|
setOnTouchListener(this::onAllAppsButtonTouch)
|
|
isHapticFeedbackEnabled =
|
|
taskbarViewCallbacks.isAllAppsButtonHapticFeedbackEnabled(mContext)
|
|
allAppsTouchRunnable = Runnable {
|
|
taskbarViewCallbacks.triggerAllAppsButtonLongClick()
|
|
allAppsTouchTriggered = true
|
|
}
|
|
val contextualSearchStateManager = ContextualSearchStateManager.INSTANCE[mContext]
|
|
if (
|
|
DeviceConfigWrapper.get().customLpaaThresholds &&
|
|
contextualSearchStateManager.lpnhDurationMillis.isPresent
|
|
) {
|
|
allAppsButtonTouchDelayMs = contextualSearchStateManager.lpnhDurationMillis.get()
|
|
}
|
|
}
|
|
|
|
@DrawableRes
|
|
private fun getAllAppsButton(isTransientTaskbar: Boolean): Int {
|
|
val shouldSelectTransientIcon =
|
|
isTransientTaskbar || (enableTaskbarPinning() && !activityContext.isThreeButtonNav)
|
|
return if (shouldSelectTransientIcon) R.drawable.ic_transient_taskbar_all_apps_search_button
|
|
else R.drawable.ic_taskbar_all_apps_search_button
|
|
}
|
|
|
|
@DimenRes
|
|
fun getAllAppsButtonTranslationXOffset(isTransientTaskbar: Boolean): Int {
|
|
return if (isTransientTaskbar) {
|
|
R.dimen.transient_taskbar_all_apps_button_translation_x_offset
|
|
} else {
|
|
R.dimen.taskbar_all_apps_search_button_translation_x_offset
|
|
}
|
|
}
|
|
|
|
private fun onAllAppsButtonTouch(view: View, ev: MotionEvent): Boolean {
|
|
when (ev.action) {
|
|
MotionEvent.ACTION_DOWN -> {
|
|
allAppsTouchTriggered = false
|
|
MAIN_EXECUTOR.handler.postDelayed(allAppsTouchRunnable!!, allAppsButtonTouchDelayMs)
|
|
}
|
|
MotionEvent.ACTION_UP,
|
|
MotionEvent.ACTION_CANCEL -> cancelAllAppsButtonTouch()
|
|
}
|
|
return false
|
|
}
|
|
|
|
private fun cancelAllAppsButtonTouch() {
|
|
MAIN_EXECUTOR.handler.removeCallbacks(allAppsTouchRunnable!!)
|
|
// ACTION_UP is first triggered, then click listener / long-click listener is triggered on
|
|
// the next frame, so we need to post twice and delay the reset.
|
|
this.post { this.post { allAppsTouchTriggered = false } }
|
|
}
|
|
|
|
private fun onAllAppsButtonClick(view: View) {
|
|
if (!allAppsTouchTriggered) {
|
|
taskbarViewCallbacks.triggerAllAppsButtonClick(view)
|
|
}
|
|
}
|
|
|
|
// Handle long click from Switch Access and Voice Access
|
|
private fun onAllAppsButtonLongClick(view: View): Boolean {
|
|
if (!MAIN_EXECUTOR.handler.hasCallbacks(allAppsTouchRunnable!!) && !allAppsTouchTriggered) {
|
|
taskbarViewCallbacks.triggerAllAppsButtonLongClick()
|
|
}
|
|
return true
|
|
}
|
|
}
|