Merge "Implement initial transient Taskbar EDU tooltips." into tm-qpr-dev am: 654f714718
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/20795522 Change-Id: Ie43422c362b180ca2d1124b1d7bf514276da101d Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -699,7 +699,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
|
||||
if (taskbarController != null && taskbarController.shouldShowEdu()) {
|
||||
if (taskbarController != null && taskbarController.shouldShowEduOnAppLaunch()) {
|
||||
// LAUNCHER_TASKBAR_EDUCATION_SHOWING is set to true here, when the education
|
||||
// flow is about to start, to avoid a race condition with other components
|
||||
// that would show something else to the user as soon as the app is opened.
|
||||
@@ -715,7 +715,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
}
|
||||
LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
|
||||
if (taskbarController != null) {
|
||||
taskbarController.showEdu();
|
||||
taskbarController.showEduOnAppLaunch();
|
||||
}
|
||||
openingTargets.release();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.view.ContextThemeWrapper;
|
||||
import android.view.LayoutInflater;
|
||||
|
||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
|
||||
@@ -32,10 +34,12 @@ public abstract class BaseTaskbarContext extends ContextThemeWrapper implements
|
||||
|
||||
protected final LayoutInflater mLayoutInflater;
|
||||
private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
|
||||
private final OnboardingPrefs<BaseTaskbarContext> mOnboardingPrefs;
|
||||
|
||||
public BaseTaskbarContext(Context windowContext) {
|
||||
super(windowContext, Themes.getActivityThemeRes(windowContext));
|
||||
mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
|
||||
mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,6 +52,11 @@ public abstract class BaseTaskbarContext extends ContextThemeWrapper implements
|
||||
return mDPChangeListeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OnboardingPrefs<BaseTaskbarContext> getOnboardingPrefs() {
|
||||
return mOnboardingPrefs;
|
||||
}
|
||||
|
||||
/** Callback invoked when a drag is initiated within this context. */
|
||||
public abstract void onDragStart();
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.launcher3.taskbar;
|
||||
import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
|
||||
|
||||
import static com.android.launcher3.QuickstepTransitionManager.TRANSIENT_TASKBAR_TRANSITION_DURATION;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_EDU_TOOLTIP;
|
||||
import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES;
|
||||
import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_RESUMED;
|
||||
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
|
||||
|
||||
@@ -259,23 +261,51 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the taskbar education flow, if the user hasn't seen it yet.
|
||||
* Starts a Taskbar EDU flow, if the user should see one upon launching an application.
|
||||
*/
|
||||
public void showEdu() {
|
||||
if (!shouldShowEdu()) {
|
||||
public void showEduOnAppLaunch() {
|
||||
if (!shouldShowEduOnAppLaunch()) {
|
||||
return;
|
||||
}
|
||||
mLauncher.getOnboardingPrefs().markChecked(OnboardingPrefs.TASKBAR_EDU_SEEN);
|
||||
|
||||
mControllers.taskbarEduController.showEdu();
|
||||
// Transient and persistent bottom sheet.
|
||||
if (!ENABLE_TASKBAR_EDU_TOOLTIP.get()) {
|
||||
mLauncher.getOnboardingPrefs().markChecked(OnboardingPrefs.TASKBAR_EDU_SEEN);
|
||||
mControllers.taskbarEduController.showEdu();
|
||||
return;
|
||||
}
|
||||
|
||||
// Persistent features EDU tooltip.
|
||||
if (!DisplayController.isTransientTaskbar(mLauncher)) {
|
||||
mControllers.taskbarEduTooltipController.maybeShowFeaturesEdu();
|
||||
return;
|
||||
}
|
||||
|
||||
// Transient swipe EDU tooltip.
|
||||
mControllers.taskbarEduTooltipController.maybeShowSwipeEdu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the taskbar education should be shown.
|
||||
* Returns {@code true} if a Taskbar education should be shown on application launch.
|
||||
*/
|
||||
public boolean shouldShowEdu() {
|
||||
return !Utilities.IS_RUNNING_IN_TEST_HARNESS
|
||||
&& !mLauncher.getOnboardingPrefs().getBoolean(OnboardingPrefs.TASKBAR_EDU_SEEN);
|
||||
public boolean shouldShowEduOnAppLaunch() {
|
||||
if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Transient and persistent bottom sheet.
|
||||
if (!ENABLE_TASKBAR_EDU_TOOLTIP.get()) {
|
||||
return !mLauncher.getOnboardingPrefs().getBoolean(OnboardingPrefs.TASKBAR_EDU_SEEN);
|
||||
}
|
||||
|
||||
// Persistent features EDU tooltip.
|
||||
if (!DisplayController.isTransientTaskbar(mLauncher)) {
|
||||
return !mLauncher.getOnboardingPrefs().hasReachedMaxCount(
|
||||
OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP);
|
||||
}
|
||||
|
||||
// Transient swipe EDU tooltip.
|
||||
return mControllers.taskbarEduTooltipController.getTooltipStep() < TOOLTIP_STEP_FEATURES;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -233,7 +233,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
new TaskbarTranslationController(this),
|
||||
isDesktopMode
|
||||
? new DesktopTaskbarRecentAppsController(this)
|
||||
: TaskbarRecentAppsController.DEFAULT);
|
||||
: TaskbarRecentAppsController.DEFAULT,
|
||||
new TaskbarEduTooltipController(this));
|
||||
}
|
||||
|
||||
public void init(@NonNull TaskbarSharedState sharedState) {
|
||||
@@ -915,6 +916,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
*/
|
||||
public void onSwipeToUnstashTaskbar() {
|
||||
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false);
|
||||
mControllers.taskbarEduTooltipController.hide();
|
||||
}
|
||||
|
||||
/** Returns {@code true} if taskbar All Apps is open. */
|
||||
|
||||
@@ -39,11 +39,14 @@ public class TaskbarAutohideSuspendController implements
|
||||
public static final int FLAG_AUTOHIDE_SUSPEND_DRAGGING = 1 << 1;
|
||||
// User has touched down but has not lifted finger.
|
||||
public static final int FLAG_AUTOHIDE_SUSPEND_TOUCHING = 1 << 2;
|
||||
// Taskbar EDU overlay is open above the Taskbar. */
|
||||
public static final int FLAG_AUTOHIDE_SUSPEND_EDU_OPEN = 1 << 3;
|
||||
|
||||
@IntDef(flag = true, value = {
|
||||
FLAG_AUTOHIDE_SUSPEND_FULLSCREEN,
|
||||
FLAG_AUTOHIDE_SUSPEND_DRAGGING,
|
||||
FLAG_AUTOHIDE_SUSPEND_TOUCHING,
|
||||
FLAG_AUTOHIDE_SUSPEND_EDU_OPEN,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AutohideSuspendFlag {}
|
||||
@@ -102,6 +105,7 @@ public class TaskbarAutohideSuspendController implements
|
||||
"FLAG_AUTOHIDE_SUSPEND_FULLSCREEN");
|
||||
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_DRAGGING, "FLAG_AUTOHIDE_SUSPEND_DRAGGING");
|
||||
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_TOUCHING, "FLAG_AUTOHIDE_SUSPEND_TOUCHING");
|
||||
appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_EDU_OPEN, "FLAG_AUTOHIDE_SUSPEND_EDU_OPEN");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public class TaskbarControllers {
|
||||
public final TaskbarRecentAppsController taskbarRecentAppsController;
|
||||
public final TaskbarTranslationController taskbarTranslationController;
|
||||
public final TaskbarOverlayController taskbarOverlayController;
|
||||
public final TaskbarEduTooltipController taskbarEduTooltipController;
|
||||
|
||||
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
|
||||
@Nullable private BackgroundRendererController[] mBackgroundRendererControllers = null;
|
||||
@@ -101,7 +102,8 @@ public class TaskbarControllers {
|
||||
TaskbarInsetsController taskbarInsetsController,
|
||||
VoiceInteractionWindowController voiceInteractionWindowController,
|
||||
TaskbarTranslationController taskbarTranslationController,
|
||||
TaskbarRecentAppsController taskbarRecentAppsController) {
|
||||
TaskbarRecentAppsController taskbarRecentAppsController,
|
||||
TaskbarEduTooltipController taskbarEduTooltipController) {
|
||||
this.taskbarActivityContext = taskbarActivityContext;
|
||||
this.taskbarDragController = taskbarDragController;
|
||||
this.navButtonController = navButtonController;
|
||||
@@ -124,6 +126,7 @@ public class TaskbarControllers {
|
||||
this.voiceInteractionWindowController = voiceInteractionWindowController;
|
||||
this.taskbarTranslationController = taskbarTranslationController;
|
||||
this.taskbarRecentAppsController = taskbarRecentAppsController;
|
||||
this.taskbarEduTooltipController = taskbarEduTooltipController;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,6 +158,7 @@ public class TaskbarControllers {
|
||||
voiceInteractionWindowController.init(this);
|
||||
taskbarRecentAppsController.init(this);
|
||||
taskbarTranslationController.init(this);
|
||||
taskbarEduTooltipController.init(this);
|
||||
|
||||
mControllersToLog = new LoggableTaskbarController[] {
|
||||
taskbarDragController, navButtonController, navbarButtonsViewController,
|
||||
@@ -162,7 +166,8 @@ public class TaskbarControllers {
|
||||
taskbarUnfoldAnimationController, taskbarKeyguardController,
|
||||
stashedHandleViewController, taskbarStashController, taskbarEduController,
|
||||
taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController,
|
||||
voiceInteractionWindowController, taskbarTranslationController
|
||||
voiceInteractionWindowController, taskbarTranslationController,
|
||||
taskbarEduTooltipController
|
||||
};
|
||||
mBackgroundRendererControllers = new BackgroundRendererController[] {
|
||||
taskbarDragLayerController, taskbarScrimViewController,
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.provider.Settings
|
||||
import android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.view.MotionEvent.ACTION_DOWN
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.Interpolator
|
||||
import com.android.launcher3.AbstractFloatingView
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.anim.AnimatorListeners
|
||||
import com.android.launcher3.popup.RoundedArrowDrawable
|
||||
import com.android.launcher3.util.Themes
|
||||
import com.android.launcher3.views.ActivityContext
|
||||
import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
|
||||
import com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE
|
||||
import com.android.systemui.animation.Interpolators.STANDARD
|
||||
|
||||
private const val ENTER_DURATION_MS = 300L
|
||||
private const val EXIT_DURATION_MS = 150L
|
||||
|
||||
/** Floating tooltip for Taskbar education. */
|
||||
class TaskbarEduTooltip
|
||||
@JvmOverloads
|
||||
constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0,
|
||||
) : AbstractFloatingView(context, attrs, defStyleAttr) {
|
||||
|
||||
private val activityContext: ActivityContext = ActivityContext.lookupContext(context)
|
||||
|
||||
private val backgroundColor =
|
||||
Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface)
|
||||
|
||||
private val tooltipCornerRadius = Themes.getDialogCornerRadius(context)
|
||||
private val arrowWidth = resources.getDimension(R.dimen.popup_arrow_width)
|
||||
private val arrowHeight = resources.getDimension(R.dimen.popup_arrow_height)
|
||||
private val arrowPointRadius = resources.getDimension(R.dimen.popup_arrow_corner_radius)
|
||||
|
||||
private val enterYDelta = resources.getDimension(R.dimen.taskbar_edu_tooltip_enter_y_delta)
|
||||
private val exitYDelta = resources.getDimension(R.dimen.taskbar_edu_tooltip_exit_y_delta)
|
||||
|
||||
/** Container where the tooltip's body should be inflated. */
|
||||
lateinit var content: ViewGroup
|
||||
private set
|
||||
private lateinit var arrow: View
|
||||
|
||||
/** Callback invoked when the tooltip is being closed. */
|
||||
var onCloseCallback: () -> Unit = {}
|
||||
private var openCloseAnimator: AnimatorSet? = null
|
||||
|
||||
/** Animates the tooltip into view. */
|
||||
fun show() {
|
||||
if (isOpen) {
|
||||
return
|
||||
}
|
||||
mIsOpen = true
|
||||
activityContext.dragLayer.addView(this)
|
||||
openCloseAnimator = createOpenCloseAnimator(isOpening = true).apply { start() }
|
||||
}
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
|
||||
content = findViewById(R.id.content)
|
||||
arrow = findViewById(R.id.arrow)
|
||||
arrow.background =
|
||||
RoundedArrowDrawable(
|
||||
arrowWidth,
|
||||
arrowHeight,
|
||||
arrowPointRadius,
|
||||
tooltipCornerRadius,
|
||||
measuredWidth.toFloat(),
|
||||
measuredHeight.toFloat(),
|
||||
(measuredWidth - arrowWidth) / 2, // arrowOffsetX
|
||||
0f, // arrowOffsetY
|
||||
false, // isPointingUp
|
||||
true, // leftAligned
|
||||
backgroundColor,
|
||||
)
|
||||
}
|
||||
|
||||
override fun handleClose(animate: Boolean) {
|
||||
if (!isOpen) {
|
||||
return
|
||||
}
|
||||
|
||||
onCloseCallback()
|
||||
if (!animate) {
|
||||
return closeComplete()
|
||||
}
|
||||
|
||||
openCloseAnimator?.cancel()
|
||||
openCloseAnimator = createOpenCloseAnimator(isOpening = false)
|
||||
openCloseAnimator?.addListener(AnimatorListeners.forEndCallback(this::closeComplete))
|
||||
openCloseAnimator?.start()
|
||||
}
|
||||
|
||||
override fun isOfType(type: Int): Boolean = type and TYPE_TASKBAR_EDUCATION_DIALOG != 0
|
||||
|
||||
override fun onControllerInterceptTouchEvent(ev: MotionEvent?): Boolean {
|
||||
if (ev?.action == ACTION_DOWN && !activityContext.dragLayer.isEventOverView(this, ev)) {
|
||||
close(true)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
Settings.Secure.putInt(mContext.contentResolver, LAUNCHER_TASKBAR_EDUCATION_SHOWING, 0)
|
||||
}
|
||||
|
||||
private fun closeComplete() {
|
||||
openCloseAnimator?.cancel()
|
||||
openCloseAnimator = null
|
||||
mIsOpen = false
|
||||
activityContext.dragLayer.removeView(this)
|
||||
}
|
||||
|
||||
private fun createOpenCloseAnimator(isOpening: Boolean): AnimatorSet {
|
||||
val duration: Long
|
||||
val alphaValues: FloatArray
|
||||
val translateYValues: FloatArray
|
||||
val fadeInterpolator: Interpolator
|
||||
val translateYInterpolator: Interpolator
|
||||
|
||||
if (isOpening) {
|
||||
duration = ENTER_DURATION_MS
|
||||
alphaValues = floatArrayOf(0f, 1f)
|
||||
translateYValues = floatArrayOf(enterYDelta, 0f)
|
||||
fadeInterpolator = STANDARD
|
||||
translateYInterpolator = EMPHASIZED_DECELERATE
|
||||
} else {
|
||||
duration = EXIT_DURATION_MS
|
||||
alphaValues = floatArrayOf(1f, 0f)
|
||||
translateYValues = floatArrayOf(0f, exitYDelta)
|
||||
fadeInterpolator = EMPHASIZED_ACCELERATE
|
||||
translateYInterpolator = EMPHASIZED_ACCELERATE
|
||||
}
|
||||
|
||||
val fade =
|
||||
ValueAnimator.ofFloat(*alphaValues).apply {
|
||||
interpolator = fadeInterpolator
|
||||
addUpdateListener {
|
||||
val alpha = it.animatedValue as Float
|
||||
content.alpha = alpha
|
||||
arrow.alpha = alpha
|
||||
}
|
||||
}
|
||||
|
||||
val translateY =
|
||||
ValueAnimator.ofFloat(*translateYValues).apply {
|
||||
interpolator = translateYInterpolator
|
||||
addUpdateListener {
|
||||
val translationY = it.animatedValue as Float
|
||||
content.translationY = translationY
|
||||
arrow.translationY = translationY
|
||||
}
|
||||
}
|
||||
|
||||
return AnimatorSet().apply {
|
||||
this.duration = duration
|
||||
playTogether(fade, translateY)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.IntDef
|
||||
import androidx.annotation.LayoutRes
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS
|
||||
import com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_EDU_TOOLTIP
|
||||
import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_EDU_OPEN
|
||||
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
|
||||
import com.android.launcher3.util.DisplayController
|
||||
import com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP
|
||||
import java.io.PrintWriter
|
||||
|
||||
/** First EDU step for swiping up to show transient Taskbar. */
|
||||
const val TOOLTIP_STEP_SWIPE = 0
|
||||
/** Second EDU step for explaining Taskbar functionality when unstashed. */
|
||||
const val TOOLTIP_STEP_FEATURES = 1
|
||||
/**
|
||||
* EDU is completed.
|
||||
*
|
||||
* This value should match the maximum count for [TASKBAR_EDU_TOOLTIP_STEP].
|
||||
*/
|
||||
const val TOOLTIP_STEP_NONE = 2
|
||||
|
||||
/** Current step in the tooltip EDU flow. */
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@IntDef(TOOLTIP_STEP_SWIPE, TOOLTIP_STEP_FEATURES, TOOLTIP_STEP_NONE)
|
||||
annotation class TaskbarEduTooltipStep
|
||||
|
||||
/** Controls stepping through the Taskbar tooltip EDU. */
|
||||
class TaskbarEduTooltipController(val activityContext: TaskbarActivityContext) :
|
||||
LoggableTaskbarController {
|
||||
|
||||
private val isTooltipEnabled = !IS_RUNNING_IN_TEST_HARNESS && ENABLE_TASKBAR_EDU_TOOLTIP.get()
|
||||
private val isOpen: Boolean
|
||||
get() = tooltip?.isOpen ?: false
|
||||
|
||||
private lateinit var controllers: TaskbarControllers
|
||||
|
||||
@TaskbarEduTooltipStep
|
||||
var tooltipStep: Int
|
||||
get() {
|
||||
return activityContext.onboardingPrefs?.getCount(TASKBAR_EDU_TOOLTIP_STEP)
|
||||
?: TOOLTIP_STEP_NONE
|
||||
}
|
||||
private set(step) {
|
||||
activityContext.onboardingPrefs?.setEventCount(step, TASKBAR_EDU_TOOLTIP_STEP)
|
||||
}
|
||||
|
||||
private var tooltip: TaskbarEduTooltip? = null
|
||||
|
||||
fun init(controllers: TaskbarControllers) {
|
||||
this.controllers = controllers
|
||||
}
|
||||
|
||||
/** Shows swipe EDU tooltip if it is the current [tooltipStep]. */
|
||||
fun maybeShowSwipeEdu() {
|
||||
if (
|
||||
!isTooltipEnabled ||
|
||||
!DisplayController.isTransientTaskbar(activityContext) ||
|
||||
tooltipStep > TOOLTIP_STEP_SWIPE
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
tooltipStep = TOOLTIP_STEP_FEATURES
|
||||
inflateTooltip(R.layout.taskbar_edu_swipe)
|
||||
tooltip?.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows feature EDU tooltip if this step has not been seen.
|
||||
*
|
||||
* If [TOOLTIP_STEP_SWIPE] has not been seen at this point, the first step is skipped because a
|
||||
* swipe up is necessary to show this step.
|
||||
*/
|
||||
fun maybeShowFeaturesEdu() {
|
||||
if (!isTooltipEnabled || tooltipStep > TOOLTIP_STEP_FEATURES) {
|
||||
return
|
||||
}
|
||||
|
||||
tooltipStep = TOOLTIP_STEP_NONE
|
||||
inflateTooltip(R.layout.taskbar_edu_features)
|
||||
tooltip?.apply {
|
||||
findViewById<View>(R.id.done_button)?.setOnClickListener { hide() }
|
||||
if (DisplayController.isTransientTaskbar(activityContext)) {
|
||||
(layoutParams as ViewGroup.MarginLayoutParams).bottomMargin +=
|
||||
activityContext.deviceProfile.taskbarSize
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
/** Closes the current [tooltip]. */
|
||||
fun hide() = tooltip?.close(true)
|
||||
|
||||
/** Initializes [tooltip] with content from [contentResId]. */
|
||||
private fun inflateTooltip(@LayoutRes contentResId: Int) {
|
||||
val overlayContext = controllers.taskbarOverlayController.requestWindow()
|
||||
val tooltip =
|
||||
overlayContext.layoutInflater.inflate(
|
||||
R.layout.taskbar_edu_tooltip,
|
||||
overlayContext.dragLayer,
|
||||
false
|
||||
) as TaskbarEduTooltip
|
||||
|
||||
controllers.taskbarAutohideSuspendController.updateFlag(
|
||||
FLAG_AUTOHIDE_SUSPEND_EDU_OPEN,
|
||||
true
|
||||
)
|
||||
tooltip.onCloseCallback = {
|
||||
this.tooltip = null
|
||||
controllers.taskbarAutohideSuspendController.updateFlag(
|
||||
FLAG_AUTOHIDE_SUSPEND_EDU_OPEN,
|
||||
false
|
||||
)
|
||||
controllers.taskbarStashController.updateAndAnimateTransientTaskbar(true)
|
||||
}
|
||||
|
||||
overlayContext.layoutInflater.inflate(contentResId, tooltip.content, true)
|
||||
this.tooltip = tooltip
|
||||
}
|
||||
|
||||
override fun dumpLogs(prefix: String?, pw: PrintWriter?) {
|
||||
pw?.println("$(prefix)TaskbarEduController:")
|
||||
pw?.println("$prefix\tisTooltipEnabled=$isTooltipEnabled")
|
||||
pw?.println("$prefix\tisOpen=$isOpen")
|
||||
pw?.println("$prefix\ttooltipStep=$tooltipStep")
|
||||
}
|
||||
}
|
||||
@@ -426,6 +426,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
return;
|
||||
}
|
||||
|
||||
if (stash && mControllers.taskbarAutohideSuspendController.isSuspended()) {
|
||||
// Avoid stashing if autohide is currently suspended.
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasAnyFlag(FLAG_STASHED_IN_APP_AUTO) != stash) {
|
||||
updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, stash);
|
||||
applyState();
|
||||
|
||||
@@ -109,8 +109,12 @@ public class TaskbarTranslationController implements TaskbarControllers.Loggable
|
||||
.setStiffness(SpringForce.STIFFNESS_LOW)
|
||||
.build(mTranslationYForSwipe, VALUE);
|
||||
mSpringBounce.addListener(forEndCallback(() -> {
|
||||
if (mGestureEnded) {
|
||||
reset();
|
||||
if (!mGestureEnded) {
|
||||
return;
|
||||
}
|
||||
reset();
|
||||
if (mControllers.taskbarStashController.isInAppAndNotStashed()) {
|
||||
mControllers.taskbarEduTooltipController.maybeShowFeaturesEdu();
|
||||
}
|
||||
}));
|
||||
mSpringBounce.start();
|
||||
|
||||
@@ -19,7 +19,6 @@ import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.dot.DotInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
@@ -30,7 +29,6 @@ import com.android.launcher3.taskbar.TaskbarControllers;
|
||||
import com.android.launcher3.taskbar.TaskbarDragController;
|
||||
import com.android.launcher3.taskbar.TaskbarStashController;
|
||||
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
|
||||
/**
|
||||
* Window context for the taskbar overlays such as All Apps and EDU.
|
||||
@@ -40,7 +38,6 @@ import com.android.launcher3.util.OnboardingPrefs;
|
||||
*/
|
||||
public class TaskbarOverlayContext extends BaseTaskbarContext {
|
||||
private final TaskbarActivityContext mTaskbarContext;
|
||||
private final OnboardingPrefs<TaskbarOverlayContext> mOnboardingPrefs;
|
||||
|
||||
private final TaskbarOverlayController mOverlayController;
|
||||
private final TaskbarDragController mDragController;
|
||||
@@ -59,7 +56,6 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
|
||||
mOverlayController = controllers.taskbarOverlayController;
|
||||
mDragController = new TaskbarDragController(this);
|
||||
mDragController.init(controllers);
|
||||
mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
|
||||
mDragLayer = new TaskbarOverlayDragLayer(this);
|
||||
|
||||
TaskbarStashController taskbarStashController = controllers.taskbarStashController;
|
||||
@@ -99,11 +95,6 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
|
||||
return mDragLayer.findViewById(R.id.apps_view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OnboardingPrefs<TaskbarOverlayContext> getOnboardingPrefs() {
|
||||
return mOnboardingPrefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBindingItems() {
|
||||
return mTaskbarContext.isBindingItems();
|
||||
|
||||
Reference in New Issue
Block a user