Merge "Use Expandable instead of View in FooterActionsViewModel (1/2)" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4017df44ea
@@ -25,7 +25,6 @@ import android.graphics.Rect
|
|||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.MathUtils
|
import android.util.MathUtils
|
||||||
import android.view.GhostView
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
@@ -86,6 +85,9 @@ constructor(
|
|||||||
*/
|
*/
|
||||||
val sourceIdentity: Any
|
val sourceIdentity: Any
|
||||||
|
|
||||||
|
/** The CUJ associated to this controller. */
|
||||||
|
val cuj: DialogCuj?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the drawing of the source in the overlay of [viewGroup].
|
* Move the drawing of the source in the overlay of [viewGroup].
|
||||||
*
|
*
|
||||||
@@ -142,7 +144,31 @@ constructor(
|
|||||||
* controlled by this controller.
|
* controlled by this controller.
|
||||||
*/
|
*/
|
||||||
// TODO(b/252723237): Make this non-nullable
|
// TODO(b/252723237): Make this non-nullable
|
||||||
fun jankConfigurationBuilder(cuj: Int): InteractionJankMonitor.Configuration.Builder?
|
fun jankConfigurationBuilder(): InteractionJankMonitor.Configuration.Builder?
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Create a [Controller] that can animate [source] to and from a dialog.
|
||||||
|
*
|
||||||
|
* Important: The view must be attached to a [ViewGroup] when calling this function and
|
||||||
|
* during the animation. For safety, this method will return null when it is not.
|
||||||
|
*
|
||||||
|
* Note: The background of [view] should be a (rounded) rectangle so that it can be
|
||||||
|
* properly animated.
|
||||||
|
*/
|
||||||
|
fun fromView(source: View, cuj: DialogCuj? = null): Controller? {
|
||||||
|
if (source.parent !is ViewGroup) {
|
||||||
|
Log.e(
|
||||||
|
TAG,
|
||||||
|
"Skipping animation as view $source is not attached to a ViewGroup",
|
||||||
|
Exception(),
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return ViewDialogLaunchAnimatorController(source, cuj)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,7 +198,12 @@ constructor(
|
|||||||
cuj: DialogCuj? = null,
|
cuj: DialogCuj? = null,
|
||||||
animateBackgroundBoundsChange: Boolean = false
|
animateBackgroundBoundsChange: Boolean = false
|
||||||
) {
|
) {
|
||||||
show(dialog, createController(view), cuj, animateBackgroundBoundsChange)
|
val controller = Controller.fromView(view, cuj)
|
||||||
|
if (controller == null) {
|
||||||
|
dialog.show()
|
||||||
|
} else {
|
||||||
|
show(dialog, controller, animateBackgroundBoundsChange)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -187,10 +218,10 @@ constructor(
|
|||||||
* Caveats: When calling this function and [dialog] is not a fullscreen dialog, then it will be
|
* Caveats: When calling this function and [dialog] is not a fullscreen dialog, then it will be
|
||||||
* made fullscreen and 2 views will be inserted between the dialog DecorView and its children.
|
* made fullscreen and 2 views will be inserted between the dialog DecorView and its children.
|
||||||
*/
|
*/
|
||||||
|
@JvmOverloads
|
||||||
fun show(
|
fun show(
|
||||||
dialog: Dialog,
|
dialog: Dialog,
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
cuj: DialogCuj? = null,
|
|
||||||
animateBackgroundBoundsChange: Boolean = false
|
animateBackgroundBoundsChange: Boolean = false
|
||||||
) {
|
) {
|
||||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||||
@@ -207,7 +238,10 @@ constructor(
|
|||||||
it.dialog.window.decorView.viewRootImpl == controller.viewRoot
|
it.dialog.window.decorView.viewRootImpl == controller.viewRoot
|
||||||
}
|
}
|
||||||
val animateFrom =
|
val animateFrom =
|
||||||
animatedParent?.dialogContentWithBackground?.let { createController(it) } ?: controller
|
animatedParent?.dialogContentWithBackground?.let {
|
||||||
|
Controller.fromView(it, controller.cuj)
|
||||||
|
}
|
||||||
|
?: controller
|
||||||
|
|
||||||
if (animatedParent == null && animateFrom !is LaunchableView) {
|
if (animatedParent == null && animateFrom !is LaunchableView) {
|
||||||
// Make sure the View we launch from implements LaunchableView to avoid visibility
|
// Make sure the View we launch from implements LaunchableView to avoid visibility
|
||||||
@@ -244,96 +278,12 @@ constructor(
|
|||||||
animateBackgroundBoundsChange,
|
animateBackgroundBoundsChange,
|
||||||
animatedParent,
|
animatedParent,
|
||||||
isForTesting,
|
isForTesting,
|
||||||
cuj,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
openedDialogs.add(animatedDialog)
|
openedDialogs.add(animatedDialog)
|
||||||
animatedDialog.start()
|
animatedDialog.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a [Controller] that can animate [source] to & from a dialog. */
|
|
||||||
private fun createController(source: View): Controller {
|
|
||||||
return object : Controller {
|
|
||||||
override val viewRoot: ViewRootImpl
|
|
||||||
get() = source.viewRootImpl
|
|
||||||
|
|
||||||
override val sourceIdentity: Any = source
|
|
||||||
|
|
||||||
override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
|
|
||||||
// Create a temporary ghost of the source (which will make it invisible) and add it
|
|
||||||
// to the host dialog.
|
|
||||||
GhostView.addGhost(source, viewGroup)
|
|
||||||
|
|
||||||
// The ghost of the source was just created, so the source is currently invisible.
|
|
||||||
// We need to make sure that it stays invisible as long as the dialog is shown or
|
|
||||||
// animating.
|
|
||||||
(source as? LaunchableView)?.setShouldBlockVisibilityChanges(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun stopDrawingInOverlay() {
|
|
||||||
// Note: here we should remove the ghost from the overlay, but in practice this is
|
|
||||||
// already done by the launch controllers created below.
|
|
||||||
|
|
||||||
// Make sure we allow the source to change its visibility again.
|
|
||||||
(source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
|
|
||||||
source.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createLaunchController(): LaunchAnimator.Controller {
|
|
||||||
val delegate = GhostedViewLaunchAnimatorController(source)
|
|
||||||
return object : LaunchAnimator.Controller by delegate {
|
|
||||||
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
|
|
||||||
// Remove the temporary ghost added by [startDrawingInOverlayOf]. Another
|
|
||||||
// ghost (that ghosts only the source content, and not its background) will
|
|
||||||
// be added right after this by the delegate and will be animated.
|
|
||||||
GhostView.removeGhost(source)
|
|
||||||
delegate.onLaunchAnimationStart(isExpandingFullyAbove)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
|
|
||||||
delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
|
|
||||||
|
|
||||||
// We hide the source when the dialog is showing. We will make this view
|
|
||||||
// visible again when dismissing the dialog. This does nothing if the source
|
|
||||||
// implements [LaunchableView], as it's already INVISIBLE in that case.
|
|
||||||
source.visibility = View.INVISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createExitController(): LaunchAnimator.Controller {
|
|
||||||
return GhostedViewLaunchAnimatorController(source)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun shouldAnimateExit(): Boolean {
|
|
||||||
// The source should be invisible by now, if it's not then something else changed
|
|
||||||
// its visibility and we probably don't want to run the animation.
|
|
||||||
if (source.visibility != View.INVISIBLE) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return source.isAttachedToWindow && ((source.parent as? View)?.isShown ?: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onExitAnimationCancelled() {
|
|
||||||
// Make sure we allow the source to change its visibility again.
|
|
||||||
(source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
|
|
||||||
|
|
||||||
// If the view is invisible it's probably because of us, so we make it visible
|
|
||||||
// again.
|
|
||||||
if (source.visibility == View.INVISIBLE) {
|
|
||||||
source.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun jankConfigurationBuilder(
|
|
||||||
cuj: Int
|
|
||||||
): InteractionJankMonitor.Configuration.Builder? {
|
|
||||||
return InteractionJankMonitor.Configuration.Builder.withView(cuj, source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch [dialog] from [another dialog][animateFrom] that was shown using [show]. This will
|
* Launch [dialog] from [another dialog][animateFrom] that was shown using [show]. This will
|
||||||
* allow for dismissing the whole stack.
|
* allow for dismissing the whole stack.
|
||||||
@@ -563,9 +513,6 @@ private class AnimatedDialog(
|
|||||||
* Whether synchronization should be disabled, which can be useful if we are running in a test.
|
* Whether synchronization should be disabled, which can be useful if we are running in a test.
|
||||||
*/
|
*/
|
||||||
private val forceDisableSynchronization: Boolean,
|
private val forceDisableSynchronization: Boolean,
|
||||||
|
|
||||||
/** Interaction to which the dialog animation is associated. */
|
|
||||||
private val cuj: DialogCuj? = null
|
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* The DecorView of this dialog window.
|
* The DecorView of this dialog window.
|
||||||
@@ -618,8 +565,9 @@ private class AnimatedDialog(
|
|||||||
private var hasInstrumentedJank = false
|
private var hasInstrumentedJank = false
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
|
val cuj = controller.cuj
|
||||||
if (cuj != null) {
|
if (cuj != null) {
|
||||||
val config = controller.jankConfigurationBuilder(cuj.cujType)
|
val config = controller.jankConfigurationBuilder()
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
if (cuj.tag != null) {
|
if (cuj.tag != null) {
|
||||||
config.setTag(cuj.tag)
|
config.setTag(cuj.tag)
|
||||||
@@ -917,7 +865,7 @@ private class AnimatedDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasInstrumentedJank) {
|
if (hasInstrumentedJank) {
|
||||||
interactionJankMonitor.end(cuj!!.cujType)
|
interactionJankMonitor.end(controller.cuj!!.cujType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -30,7 +30,12 @@ interface Expandable {
|
|||||||
*/
|
*/
|
||||||
fun activityLaunchController(cujType: Int? = null): ActivityLaunchAnimator.Controller?
|
fun activityLaunchController(cujType: Int? = null): ActivityLaunchAnimator.Controller?
|
||||||
|
|
||||||
// TODO(b/230830644): Introduce DialogLaunchAnimator and a function to expose it here.
|
/**
|
||||||
|
* Create a [DialogLaunchAnimator.Controller] that can be used to expand this [Expandable] into
|
||||||
|
* a Dialog, or return `null` if this [Expandable] should not be animated (e.g. if it is
|
||||||
|
* currently not attached or visible).
|
||||||
|
*/
|
||||||
|
fun dialogLaunchController(cuj: DialogCuj? = null): DialogLaunchAnimator.Controller?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +44,7 @@ interface Expandable {
|
|||||||
* Note: The background of [view] should be a (rounded) rectangle so that it can be properly
|
* Note: The background of [view] should be a (rounded) rectangle so that it can be properly
|
||||||
* animated.
|
* animated.
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
fun fromView(view: View): Expandable {
|
fun fromView(view: View): Expandable {
|
||||||
return object : Expandable {
|
return object : Expandable {
|
||||||
override fun activityLaunchController(
|
override fun activityLaunchController(
|
||||||
@@ -46,6 +52,12 @@ interface Expandable {
|
|||||||
): ActivityLaunchAnimator.Controller? {
|
): ActivityLaunchAnimator.Controller? {
|
||||||
return ActivityLaunchAnimator.Controller.fromView(view, cujType)
|
return ActivityLaunchAnimator.Controller.fromView(view, cujType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dialogLaunchController(
|
||||||
|
cuj: DialogCuj?
|
||||||
|
): DialogLaunchAnimator.Controller? {
|
||||||
|
return DialogLaunchAnimator.Controller.fromView(view, cuj)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.systemui.animation
|
||||||
|
|
||||||
|
import android.view.GhostView
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.ViewRootImpl
|
||||||
|
import com.android.internal.jank.InteractionJankMonitor
|
||||||
|
|
||||||
|
/** A [DialogLaunchAnimator.Controller] that can animate a [View] from/to a dialog. */
|
||||||
|
class ViewDialogLaunchAnimatorController
|
||||||
|
internal constructor(
|
||||||
|
private val source: View,
|
||||||
|
override val cuj: DialogCuj?,
|
||||||
|
) : DialogLaunchAnimator.Controller {
|
||||||
|
override val viewRoot: ViewRootImpl
|
||||||
|
get() = source.viewRootImpl
|
||||||
|
|
||||||
|
override val sourceIdentity: Any = source
|
||||||
|
|
||||||
|
override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
|
||||||
|
// Create a temporary ghost of the source (which will make it invisible) and add it
|
||||||
|
// to the host dialog.
|
||||||
|
GhostView.addGhost(source, viewGroup)
|
||||||
|
|
||||||
|
// The ghost of the source was just created, so the source is currently invisible.
|
||||||
|
// We need to make sure that it stays invisible as long as the dialog is shown or
|
||||||
|
// animating.
|
||||||
|
(source as? LaunchableView)?.setShouldBlockVisibilityChanges(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopDrawingInOverlay() {
|
||||||
|
// Note: here we should remove the ghost from the overlay, but in practice this is
|
||||||
|
// already done by the launch controllers created below.
|
||||||
|
|
||||||
|
// Make sure we allow the source to change its visibility again.
|
||||||
|
(source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
|
||||||
|
source.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createLaunchController(): LaunchAnimator.Controller {
|
||||||
|
val delegate = GhostedViewLaunchAnimatorController(source)
|
||||||
|
return object : LaunchAnimator.Controller by delegate {
|
||||||
|
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
|
||||||
|
// Remove the temporary ghost added by [startDrawingInOverlayOf]. Another
|
||||||
|
// ghost (that ghosts only the source content, and not its background) will
|
||||||
|
// be added right after this by the delegate and will be animated.
|
||||||
|
GhostView.removeGhost(source)
|
||||||
|
delegate.onLaunchAnimationStart(isExpandingFullyAbove)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
|
||||||
|
delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
|
||||||
|
|
||||||
|
// We hide the source when the dialog is showing. We will make this view
|
||||||
|
// visible again when dismissing the dialog. This does nothing if the source
|
||||||
|
// implements [LaunchableView], as it's already INVISIBLE in that case.
|
||||||
|
source.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createExitController(): LaunchAnimator.Controller {
|
||||||
|
return GhostedViewLaunchAnimatorController(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldAnimateExit(): Boolean {
|
||||||
|
// The source should be invisible by now, if it's not then something else changed
|
||||||
|
// its visibility and we probably don't want to run the animation.
|
||||||
|
if (source.visibility != View.INVISIBLE) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return source.isAttachedToWindow && ((source.parent as? View)?.isShown ?: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onExitAnimationCancelled() {
|
||||||
|
// Make sure we allow the source to change its visibility again.
|
||||||
|
(source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
|
||||||
|
|
||||||
|
// If the view is invisible it's probably because of us, so we make it visible
|
||||||
|
// again.
|
||||||
|
if (source.visibility == View.INVISIBLE) {
|
||||||
|
source.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun jankConfigurationBuilder(): InteractionJankMonitor.Configuration.Builder? {
|
||||||
|
val type = cuj?.cujType ?: return null
|
||||||
|
return InteractionJankMonitor.Configuration.Builder.withView(type, source)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,17 +40,16 @@ import androidx.compose.ui.unit.Density
|
|||||||
import androidx.compose.ui.unit.LayoutDirection
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
import com.android.internal.jank.InteractionJankMonitor
|
import com.android.internal.jank.InteractionJankMonitor
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||||
|
import com.android.systemui.animation.DialogCuj
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator
|
import com.android.systemui.animation.DialogLaunchAnimator
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.animation.LaunchAnimator
|
import com.android.systemui.animation.LaunchAnimator
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/** A controller that can control animated launches. */
|
/** A controller that can control animated launches from an [Expandable]. */
|
||||||
interface ExpandableController {
|
interface ExpandableController {
|
||||||
/** Create an [ActivityLaunchAnimator.Controller] to animate into an Activity. */
|
/** The [Expandable] controlled by this controller. */
|
||||||
fun forActivity(): ActivityLaunchAnimator.Controller
|
val expandable: Expandable
|
||||||
|
|
||||||
/** Create a [DialogLaunchAnimator.Controller] to animate into a Dialog. */
|
|
||||||
fun forDialog(): DialogLaunchAnimator.Controller
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,12 +119,25 @@ internal class ExpandableControllerImpl(
|
|||||||
private val layoutDirection: LayoutDirection,
|
private val layoutDirection: LayoutDirection,
|
||||||
private val isComposed: State<Boolean>,
|
private val isComposed: State<Boolean>,
|
||||||
) : ExpandableController {
|
) : ExpandableController {
|
||||||
override fun forActivity(): ActivityLaunchAnimator.Controller {
|
override val expandable: Expandable =
|
||||||
return activityController()
|
object : Expandable {
|
||||||
|
override fun activityLaunchController(
|
||||||
|
cujType: Int?,
|
||||||
|
): ActivityLaunchAnimator.Controller? {
|
||||||
|
if (!isComposed.value) {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun forDialog(): DialogLaunchAnimator.Controller {
|
return activityController(cujType)
|
||||||
return dialogController()
|
}
|
||||||
|
|
||||||
|
override fun dialogLaunchController(cuj: DialogCuj?): DialogLaunchAnimator.Controller? {
|
||||||
|
if (!isComposed.value) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return dialogController(cuj)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -233,7 +245,7 @@ internal class ExpandableControllerImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Create an [ActivityLaunchAnimator.Controller] that can be used to animate activities. */
|
/** Create an [ActivityLaunchAnimator.Controller] that can be used to animate activities. */
|
||||||
private fun activityController(): ActivityLaunchAnimator.Controller {
|
private fun activityController(cujType: Int?): ActivityLaunchAnimator.Controller {
|
||||||
val delegate = launchController()
|
val delegate = launchController()
|
||||||
return object : ActivityLaunchAnimator.Controller, LaunchAnimator.Controller by delegate {
|
return object : ActivityLaunchAnimator.Controller, LaunchAnimator.Controller by delegate {
|
||||||
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
|
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
|
||||||
@@ -248,10 +260,11 @@ internal class ExpandableControllerImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun dialogController(): DialogLaunchAnimator.Controller {
|
private fun dialogController(cuj: DialogCuj?): DialogLaunchAnimator.Controller {
|
||||||
return object : DialogLaunchAnimator.Controller {
|
return object : DialogLaunchAnimator.Controller {
|
||||||
override val viewRoot: ViewRootImpl = composeViewRoot.viewRootImpl
|
override val viewRoot: ViewRootImpl = composeViewRoot.viewRootImpl
|
||||||
override val sourceIdentity: Any = this@ExpandableControllerImpl
|
override val sourceIdentity: Any = this@ExpandableControllerImpl
|
||||||
|
override val cuj: DialogCuj? = cuj
|
||||||
|
|
||||||
override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
|
override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
|
||||||
val newOverlay = viewGroup.overlay as ViewGroupOverlay
|
val newOverlay = viewGroup.overlay as ViewGroupOverlay
|
||||||
@@ -294,9 +307,7 @@ internal class ExpandableControllerImpl(
|
|||||||
isDialogShowing.value = false
|
isDialogShowing.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun jankConfigurationBuilder(
|
override fun jankConfigurationBuilder(): InteractionJankMonitor.Configuration.Builder? {
|
||||||
cuj: Int
|
|
||||||
): InteractionJankMonitor.Configuration.Builder? {
|
|
||||||
// TODO(b/252723237): Add support for jank monitoring when animating from a
|
// TODO(b/252723237): Add support for jank monitoring when animating from a
|
||||||
// Composable.
|
// Composable.
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ import com.android.systemui.MultiListLayout;
|
|||||||
import com.android.systemui.MultiListLayout.MultiListAdapter;
|
import com.android.systemui.MultiListLayout.MultiListAdapter;
|
||||||
import com.android.systemui.animation.DialogCuj;
|
import com.android.systemui.animation.DialogCuj;
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
|
import com.android.systemui.animation.Expandable;
|
||||||
import com.android.systemui.animation.Interpolators;
|
import com.android.systemui.animation.Interpolators;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
||||||
@@ -448,10 +449,11 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
|||||||
*
|
*
|
||||||
* @param keyguardShowing True if keyguard is showing
|
* @param keyguardShowing True if keyguard is showing
|
||||||
* @param isDeviceProvisioned True if device is provisioned
|
* @param isDeviceProvisioned True if device is provisioned
|
||||||
* @param view The view from which we should animate the dialog when showing it
|
* @param expandable The expandable from which we should animate the dialog when
|
||||||
|
* showing it
|
||||||
*/
|
*/
|
||||||
public void showOrHideDialog(boolean keyguardShowing, boolean isDeviceProvisioned,
|
public void showOrHideDialog(boolean keyguardShowing, boolean isDeviceProvisioned,
|
||||||
@Nullable View view) {
|
@Nullable Expandable expandable) {
|
||||||
mKeyguardShowing = keyguardShowing;
|
mKeyguardShowing = keyguardShowing;
|
||||||
mDeviceProvisioned = isDeviceProvisioned;
|
mDeviceProvisioned = isDeviceProvisioned;
|
||||||
if (mDialog != null && mDialog.isShowing()) {
|
if (mDialog != null && mDialog.isShowing()) {
|
||||||
@@ -463,7 +465,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
|||||||
mDialog.dismiss();
|
mDialog.dismiss();
|
||||||
mDialog = null;
|
mDialog = null;
|
||||||
} else {
|
} else {
|
||||||
handleShow(view);
|
handleShow(expandable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +497,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleShow(@Nullable View view) {
|
protected void handleShow(@Nullable Expandable expandable) {
|
||||||
awakenIfNecessary();
|
awakenIfNecessary();
|
||||||
mDialog = createDialog();
|
mDialog = createDialog();
|
||||||
prepareDialog();
|
prepareDialog();
|
||||||
@@ -507,10 +509,12 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
|
|||||||
// Don't acquire soft keyboard focus, to avoid destroying state when capturing bugreports
|
// Don't acquire soft keyboard focus, to avoid destroying state when capturing bugreports
|
||||||
mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
|
mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
|
||||||
|
|
||||||
if (view != null) {
|
DialogLaunchAnimator.Controller controller =
|
||||||
mDialogLaunchAnimator.showFromView(mDialog, view,
|
expandable != null ? expandable.dialogLaunchController(
|
||||||
new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
|
new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
|
||||||
INTERACTION_JANK_TAG));
|
INTERACTION_JANK_TAG)) : null;
|
||||||
|
if (controller != null) {
|
||||||
|
mDialogLaunchAnimator.show(mDialog, controller);
|
||||||
} else {
|
} else {
|
||||||
mDialog.show();
|
mDialog.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import com.android.systemui.Dumpable
|
|||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.animation.DialogCuj
|
import com.android.systemui.animation.DialogCuj
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator
|
import com.android.systemui.animation.DialogLaunchAnimator
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.dagger.qualifiers.Background
|
import com.android.systemui.dagger.qualifiers.Background
|
||||||
@@ -98,10 +99,10 @@ interface FgsManagerController {
|
|||||||
fun init()
|
fun init()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the foreground services dialog. The dialog will be expanded from [viewLaunchedFrom] if
|
* Show the foreground services dialog. The dialog will be expanded from [expandable] if
|
||||||
* it's not `null`.
|
* it's not `null`.
|
||||||
*/
|
*/
|
||||||
fun showDialog(viewLaunchedFrom: View?)
|
fun showDialog(expandable: Expandable?)
|
||||||
|
|
||||||
/** Add a [OnNumberOfPackagesChangedListener]. */
|
/** Add a [OnNumberOfPackagesChangedListener]. */
|
||||||
fun addOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener)
|
fun addOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener)
|
||||||
@@ -367,7 +368,7 @@ class FgsManagerControllerImpl @Inject constructor(
|
|||||||
|
|
||||||
override fun shouldUpdateFooterVisibility() = dialog == null
|
override fun shouldUpdateFooterVisibility() = dialog == null
|
||||||
|
|
||||||
override fun showDialog(viewLaunchedFrom: View?) {
|
override fun showDialog(expandable: Expandable?) {
|
||||||
synchronized(lock) {
|
synchronized(lock) {
|
||||||
if (dialog == null) {
|
if (dialog == null) {
|
||||||
|
|
||||||
@@ -403,16 +404,18 @@ class FgsManagerControllerImpl @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mainExecutor.execute {
|
mainExecutor.execute {
|
||||||
viewLaunchedFrom
|
val controller =
|
||||||
?.let {
|
expandable?.dialogLaunchController(
|
||||||
dialogLaunchAnimator.showFromView(
|
DialogCuj(
|
||||||
dialog, it,
|
|
||||||
cuj = DialogCuj(
|
|
||||||
InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
|
InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
|
||||||
INTERACTION_JANK_TAG
|
INTERACTION_JANK_TAG,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} ?: dialog.show()
|
if (controller != null) {
|
||||||
|
dialogLaunchAnimator.show(dialog, controller)
|
||||||
|
} else {
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backgroundExecutor.execute {
|
backgroundExecutor.execute {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import com.android.internal.logging.nano.MetricsProto
|
|||||||
import com.android.keyguard.KeyguardUpdateMonitor
|
import com.android.keyguard.KeyguardUpdateMonitor
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.globalactions.GlobalActionsDialogLite
|
import com.android.systemui.globalactions.GlobalActionsDialogLite
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.plugins.FalsingManager
|
import com.android.systemui.plugins.FalsingManager
|
||||||
@@ -156,7 +157,7 @@ internal class FooterActionsController @Inject constructor(
|
|||||||
startSettingsActivity()
|
startSettingsActivity()
|
||||||
} else if (v === powerMenuLite) {
|
} else if (v === powerMenuLite) {
|
||||||
uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
|
uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
|
||||||
globalActionsDialog?.showOrHideDialog(false, true, v)
|
globalActionsDialog?.showOrHideDialog(false, true, Expandable.fromView(powerMenuLite))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.widget.TextView;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.animation.Expandable;
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.qs.dagger.QSScope;
|
import com.android.systemui.qs.dagger.QSScope;
|
||||||
@@ -130,7 +131,7 @@ public class QSFgsManagerFooter implements View.OnClickListener,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
mFgsManagerController.showDialog(mRootView);
|
mFgsManagerController.showDialog(Expandable.fromView(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshState() {
|
public void refreshState() {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import androidx.annotation.Nullable;
|
|||||||
import com.android.internal.util.FrameworkStatsLog;
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
import com.android.systemui.FontSizeUtils;
|
import com.android.systemui.FontSizeUtils;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.animation.Expandable;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.common.shared.model.Icon;
|
import com.android.systemui.common.shared.model.Icon;
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
@@ -169,7 +170,7 @@ public class QSSecurityFooter extends ViewController<View>
|
|||||||
|
|
||||||
// TODO(b/242040009): Remove this.
|
// TODO(b/242040009): Remove this.
|
||||||
public void showDeviceMonitoringDialog() {
|
public void showDeviceMonitoringDialog() {
|
||||||
mQSSecurityFooterUtils.showDeviceMonitoringDialog(mContext, mView);
|
mQSSecurityFooterUtils.showDeviceMonitoringDialog(mContext, Expandable.fromView(mView));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshState() {
|
public void refreshState() {
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ import com.android.internal.jank.InteractionJankMonitor;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.animation.DialogCuj;
|
import com.android.systemui.animation.DialogCuj;
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
|
import com.android.systemui.animation.Expandable;
|
||||||
import com.android.systemui.common.shared.model.ContentDescription;
|
import com.android.systemui.common.shared.model.ContentDescription;
|
||||||
import com.android.systemui.common.shared.model.Icon;
|
import com.android.systemui.common.shared.model.Icon;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
@@ -190,8 +191,9 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Show the device monitoring dialog. */
|
/** Show the device monitoring dialog. */
|
||||||
public void showDeviceMonitoringDialog(Context quickSettingsContext, @Nullable View view) {
|
public void showDeviceMonitoringDialog(Context quickSettingsContext,
|
||||||
createDialog(quickSettingsContext, view);
|
@Nullable Expandable expandable) {
|
||||||
|
createDialog(quickSettingsContext, expandable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -440,7 +442,7 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDialog(Context quickSettingsContext, @Nullable View view) {
|
private void createDialog(Context quickSettingsContext, @Nullable Expandable expandable) {
|
||||||
mShouldUseSettingsButton.set(false);
|
mShouldUseSettingsButton.set(false);
|
||||||
mBgHandler.post(() -> {
|
mBgHandler.post(() -> {
|
||||||
String settingsButtonText = getSettingsButton();
|
String settingsButtonText = getSettingsButton();
|
||||||
@@ -453,9 +455,12 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
|
|||||||
? settingsButtonText : getNegativeButton(), this);
|
? settingsButtonText : getNegativeButton(), this);
|
||||||
|
|
||||||
mDialog.setView(dialogView);
|
mDialog.setView(dialogView);
|
||||||
if (view != null && view.isAggregatedVisible()) {
|
DialogLaunchAnimator.Controller controller =
|
||||||
mDialogLaunchAnimator.showFromView(mDialog, view, new DialogCuj(
|
expandable != null ? expandable.dialogLaunchController(new DialogCuj(
|
||||||
InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG));
|
InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG))
|
||||||
|
: null;
|
||||||
|
if (controller != null) {
|
||||||
|
mDialogLaunchAnimator.show(mDialog, controller);
|
||||||
} else {
|
} else {
|
||||||
mDialog.show();
|
mDialog.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,11 @@ import android.content.Intent
|
|||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.view.View
|
|
||||||
import com.android.internal.jank.InteractionJankMonitor
|
import com.android.internal.jank.InteractionJankMonitor
|
||||||
import com.android.internal.logging.MetricsLogger
|
import com.android.internal.logging.MetricsLogger
|
||||||
import com.android.internal.logging.UiEventLogger
|
import com.android.internal.logging.UiEventLogger
|
||||||
import com.android.internal.logging.nano.MetricsProto
|
import com.android.internal.logging.nano.MetricsProto
|
||||||
import com.android.internal.util.FrameworkStatsLog
|
import com.android.internal.util.FrameworkStatsLog
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
|
||||||
import com.android.systemui.animation.Expandable
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
@@ -74,37 +72,27 @@ interface FooterActionsInteractor {
|
|||||||
val deviceMonitoringDialogRequests: Flow<Unit>
|
val deviceMonitoringDialogRequests: Flow<Unit>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the device monitoring dialog, expanded from [view].
|
* Show the device monitoring dialog, expanded from [expandable] if it's not null.
|
||||||
*
|
|
||||||
* Important: [view] must be associated to the same [Context] as the [Quick Settings fragment]
|
|
||||||
* [com.android.systemui.qs.QSFragment].
|
|
||||||
*/
|
|
||||||
// TODO(b/230830644): Replace view by Expandable interface.
|
|
||||||
fun showDeviceMonitoringDialog(view: View)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the device monitoring dialog.
|
|
||||||
*
|
*
|
||||||
* Important: [quickSettingsContext] *must* be the [Context] associated to the [Quick Settings
|
* Important: [quickSettingsContext] *must* be the [Context] associated to the [Quick Settings
|
||||||
* fragment][com.android.systemui.qs.QSFragment].
|
* fragment][com.android.systemui.qs.QSFragment].
|
||||||
*/
|
*/
|
||||||
// TODO(b/230830644): Replace view by Expandable interface.
|
fun showDeviceMonitoringDialog(quickSettingsContext: Context, expandable: Expandable?)
|
||||||
fun showDeviceMonitoringDialog(quickSettingsContext: Context)
|
|
||||||
|
|
||||||
/** Show the foreground services dialog. */
|
/** Show the foreground services dialog. */
|
||||||
// TODO(b/230830644): Replace view by Expandable interface.
|
fun showForegroundServicesDialog(expandable: Expandable)
|
||||||
fun showForegroundServicesDialog(view: View)
|
|
||||||
|
|
||||||
/** Show the power menu dialog. */
|
/** Show the power menu dialog. */
|
||||||
// TODO(b/230830644): Replace view by Expandable interface.
|
fun showPowerMenuDialog(
|
||||||
fun showPowerMenuDialog(globalActionsDialogLite: GlobalActionsDialogLite, view: View)
|
globalActionsDialogLite: GlobalActionsDialogLite,
|
||||||
|
expandable: Expandable,
|
||||||
|
)
|
||||||
|
|
||||||
/** Show the settings. */
|
/** Show the settings. */
|
||||||
fun showSettings(expandable: Expandable)
|
fun showSettings(expandable: Expandable)
|
||||||
|
|
||||||
/** Show the user switcher. */
|
/** Show the user switcher. */
|
||||||
// TODO(b/230830644): Replace view by Expandable interface.
|
fun showUserSwitcher(context: Context, expandable: Expandable)
|
||||||
fun showUserSwitcher(view: View)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@@ -147,28 +135,32 @@ constructor(
|
|||||||
null,
|
null,
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun showDeviceMonitoringDialog(view: View) {
|
override fun showDeviceMonitoringDialog(
|
||||||
qsSecurityFooterUtils.showDeviceMonitoringDialog(view.context, view)
|
quickSettingsContext: Context,
|
||||||
|
expandable: Expandable?,
|
||||||
|
) {
|
||||||
|
qsSecurityFooterUtils.showDeviceMonitoringDialog(quickSettingsContext, expandable)
|
||||||
|
if (expandable != null) {
|
||||||
DevicePolicyEventLogger.createEvent(
|
DevicePolicyEventLogger.createEvent(
|
||||||
FrameworkStatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED
|
FrameworkStatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED
|
||||||
)
|
)
|
||||||
.write()
|
.write()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showDeviceMonitoringDialog(quickSettingsContext: Context) {
|
|
||||||
qsSecurityFooterUtils.showDeviceMonitoringDialog(quickSettingsContext, /* view= */ null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showForegroundServicesDialog(view: View) {
|
override fun showForegroundServicesDialog(expandable: Expandable) {
|
||||||
fgsManagerController.showDialog(view)
|
fgsManagerController.showDialog(expandable)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showPowerMenuDialog(globalActionsDialogLite: GlobalActionsDialogLite, view: View) {
|
override fun showPowerMenuDialog(
|
||||||
|
globalActionsDialogLite: GlobalActionsDialogLite,
|
||||||
|
expandable: Expandable,
|
||||||
|
) {
|
||||||
uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
|
uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
|
||||||
globalActionsDialogLite.showOrHideDialog(
|
globalActionsDialogLite.showOrHideDialog(
|
||||||
/* keyguardShowing= */ false,
|
/* keyguardShowing= */ false,
|
||||||
/* isDeviceProvisioned= */ true,
|
/* isDeviceProvisioned= */ true,
|
||||||
view,
|
expandable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,21 +181,21 @@ constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showUserSwitcher(view: View) {
|
override fun showUserSwitcher(context: Context, expandable: Expandable) {
|
||||||
if (!featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)) {
|
if (!featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)) {
|
||||||
userSwitchDialogController.showDialog(view)
|
userSwitchDialogController.showDialog(context, expandable)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val intent =
|
val intent =
|
||||||
Intent(view.context, UserSwitcherActivity::class.java).apply {
|
Intent(context, UserSwitcherActivity::class.java).apply {
|
||||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
|
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
}
|
}
|
||||||
|
|
||||||
activityStarter.startActivity(
|
activityStarter.startActivity(
|
||||||
intent,
|
intent,
|
||||||
true /* dismissShade */,
|
true /* dismissShade */,
|
||||||
ActivityLaunchAnimator.Controller.fromView(view, null),
|
expandable.activityLaunchController(),
|
||||||
true /* showOverlockscreenwhenlocked */,
|
true /* showOverlockscreenwhenlocked */,
|
||||||
UserHandle.SYSTEM,
|
UserHandle.SYSTEM,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import androidx.lifecycle.LifecycleOwner
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.common.ui.binder.IconViewBinder
|
import com.android.systemui.common.ui.binder.IconViewBinder
|
||||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||||
import com.android.systemui.people.ui.view.PeopleViewBinder.bind
|
import com.android.systemui.people.ui.view.PeopleViewBinder.bind
|
||||||
@@ -125,7 +126,7 @@ object FooterActionsViewBinder {
|
|||||||
launch {
|
launch {
|
||||||
viewModel.security.collect { security ->
|
viewModel.security.collect { security ->
|
||||||
if (previousSecurity != security) {
|
if (previousSecurity != security) {
|
||||||
bindSecurity(securityHolder, security)
|
bindSecurity(view.context, securityHolder, security)
|
||||||
previousSecurity = security
|
previousSecurity = security
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,6 +160,7 @@ object FooterActionsViewBinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun bindSecurity(
|
private fun bindSecurity(
|
||||||
|
quickSettingsContext: Context,
|
||||||
securityHolder: TextButtonViewHolder,
|
securityHolder: TextButtonViewHolder,
|
||||||
security: FooterActionsSecurityButtonViewModel?,
|
security: FooterActionsSecurityButtonViewModel?,
|
||||||
) {
|
) {
|
||||||
@@ -171,9 +173,12 @@ object FooterActionsViewBinder {
|
|||||||
// Make sure that the chevron is visible and that the button is clickable if there is a
|
// Make sure that the chevron is visible and that the button is clickable if there is a
|
||||||
// listener.
|
// listener.
|
||||||
val chevron = securityHolder.chevron
|
val chevron = securityHolder.chevron
|
||||||
if (security.onClick != null) {
|
val onClick = security.onClick
|
||||||
|
if (onClick != null) {
|
||||||
securityView.isClickable = true
|
securityView.isClickable = true
|
||||||
securityView.setOnClickListener(security.onClick)
|
securityView.setOnClickListener {
|
||||||
|
onClick(quickSettingsContext, Expandable.fromView(securityView))
|
||||||
|
}
|
||||||
chevron.isVisible = true
|
chevron.isVisible = true
|
||||||
} else {
|
} else {
|
||||||
securityView.isClickable = false
|
securityView.isClickable = false
|
||||||
@@ -205,7 +210,9 @@ object FooterActionsViewBinder {
|
|||||||
foregroundServicesWithNumberView.isVisible = false
|
foregroundServicesWithNumberView.isVisible = false
|
||||||
|
|
||||||
foregroundServicesWithTextView.isVisible = true
|
foregroundServicesWithTextView.isVisible = true
|
||||||
foregroundServicesWithTextView.setOnClickListener(foregroundServices.onClick)
|
foregroundServicesWithTextView.setOnClickListener {
|
||||||
|
foregroundServices.onClick(Expandable.fromView(foregroundServicesWithTextView))
|
||||||
|
}
|
||||||
foregroundServicesWithTextHolder.text.text = foregroundServices.text
|
foregroundServicesWithTextHolder.text.text = foregroundServices.text
|
||||||
foregroundServicesWithTextHolder.newDot.isVisible = foregroundServices.hasNewChanges
|
foregroundServicesWithTextHolder.newDot.isVisible = foregroundServices.hasNewChanges
|
||||||
} else {
|
} else {
|
||||||
@@ -213,7 +220,9 @@ object FooterActionsViewBinder {
|
|||||||
foregroundServicesWithTextView.isVisible = false
|
foregroundServicesWithTextView.isVisible = false
|
||||||
|
|
||||||
foregroundServicesWithNumberView.visibility = View.VISIBLE
|
foregroundServicesWithNumberView.visibility = View.VISIBLE
|
||||||
foregroundServicesWithNumberView.setOnClickListener(foregroundServices.onClick)
|
foregroundServicesWithNumberView.setOnClickListener {
|
||||||
|
foregroundServices.onClick(Expandable.fromView(foregroundServicesWithTextView))
|
||||||
|
}
|
||||||
foregroundServicesWithNumberHolder.number.text = foregroundServicesCount.toString()
|
foregroundServicesWithNumberHolder.number.text = foregroundServicesCount.toString()
|
||||||
foregroundServicesWithNumberHolder.number.contentDescription = foregroundServices.text
|
foregroundServicesWithNumberHolder.number.contentDescription = foregroundServices.text
|
||||||
foregroundServicesWithNumberHolder.newDot.isVisible = foregroundServices.hasNewChanges
|
foregroundServicesWithNumberHolder.newDot.isVisible = foregroundServices.hasNewChanges
|
||||||
@@ -229,7 +238,7 @@ object FooterActionsViewBinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buttonView.setBackgroundResource(model.background)
|
buttonView.setBackgroundResource(model.background)
|
||||||
buttonView.setOnClickListener(model.onClick)
|
buttonView.setOnClickListener { model.onClick(Expandable.fromView(buttonView)) }
|
||||||
|
|
||||||
val icon = model.icon
|
val icon = model.icon
|
||||||
val iconView = button.icon
|
val iconView = button.icon
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
package com.android.systemui.qs.footer.ui.viewmodel
|
package com.android.systemui.qs.footer.ui.viewmodel
|
||||||
|
|
||||||
import android.annotation.DrawableRes
|
import android.annotation.DrawableRes
|
||||||
import android.view.View
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.common.shared.model.Icon
|
import com.android.systemui.common.shared.model.Icon
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +29,5 @@ data class FooterActionsButtonViewModel(
|
|||||||
val icon: Icon,
|
val icon: Icon,
|
||||||
val iconTint: Int?,
|
val iconTint: Int?,
|
||||||
@DrawableRes val background: Int,
|
@DrawableRes val background: Int,
|
||||||
// TODO(b/230830644): Replace View by an Expandable interface that can expand in either dialog
|
val onClick: (Expandable) -> Unit,
|
||||||
// or activity.
|
|
||||||
val onClick: (View) -> Unit,
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.systemui.qs.footer.ui.viewmodel
|
package com.android.systemui.qs.footer.ui.viewmodel
|
||||||
|
|
||||||
import android.view.View
|
import com.android.systemui.animation.Expandable
|
||||||
|
|
||||||
/** A ViewModel for the foreground services button. */
|
/** A ViewModel for the foreground services button. */
|
||||||
data class FooterActionsForegroundServicesButtonViewModel(
|
data class FooterActionsForegroundServicesButtonViewModel(
|
||||||
@@ -24,5 +24,5 @@ data class FooterActionsForegroundServicesButtonViewModel(
|
|||||||
val text: String,
|
val text: String,
|
||||||
val displayText: Boolean,
|
val displayText: Boolean,
|
||||||
val hasNewChanges: Boolean,
|
val hasNewChanges: Boolean,
|
||||||
val onClick: (View) -> Unit,
|
val onClick: (Expandable) -> Unit,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,12 +16,13 @@
|
|||||||
|
|
||||||
package com.android.systemui.qs.footer.ui.viewmodel
|
package com.android.systemui.qs.footer.ui.viewmodel
|
||||||
|
|
||||||
import android.view.View
|
import android.content.Context
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.common.shared.model.Icon
|
import com.android.systemui.common.shared.model.Icon
|
||||||
|
|
||||||
/** A ViewModel for the security button. */
|
/** A ViewModel for the security button. */
|
||||||
data class FooterActionsSecurityButtonViewModel(
|
data class FooterActionsSecurityButtonViewModel(
|
||||||
val icon: Icon,
|
val icon: Icon,
|
||||||
val text: String,
|
val text: String,
|
||||||
val onClick: ((View) -> Unit)?,
|
val onClick: ((quickSettingsContext: Context, Expandable) -> Unit)?,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.android.systemui.qs.footer.ui.viewmodel
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
@@ -199,50 +198,51 @@ class FooterActionsViewModel(
|
|||||||
*/
|
*/
|
||||||
suspend fun observeDeviceMonitoringDialogRequests(quickSettingsContext: Context) {
|
suspend fun observeDeviceMonitoringDialogRequests(quickSettingsContext: Context) {
|
||||||
footerActionsInteractor.deviceMonitoringDialogRequests.collect {
|
footerActionsInteractor.deviceMonitoringDialogRequests.collect {
|
||||||
footerActionsInteractor.showDeviceMonitoringDialog(quickSettingsContext)
|
footerActionsInteractor.showDeviceMonitoringDialog(
|
||||||
|
quickSettingsContext,
|
||||||
|
expandable = null,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSecurityButtonClicked(view: View) {
|
private fun onSecurityButtonClicked(quickSettingsContext: Context, expandable: Expandable) {
|
||||||
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
footerActionsInteractor.showDeviceMonitoringDialog(view)
|
footerActionsInteractor.showDeviceMonitoringDialog(quickSettingsContext, expandable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onForegroundServiceButtonClicked(view: View) {
|
private fun onForegroundServiceButtonClicked(expandable: Expandable) {
|
||||||
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
footerActionsInteractor.showForegroundServicesDialog(view)
|
footerActionsInteractor.showForegroundServicesDialog(expandable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onUserSwitcherClicked(view: View) {
|
private fun onUserSwitcherClicked(expandable: Expandable) {
|
||||||
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
footerActionsInteractor.showUserSwitcher(view)
|
footerActionsInteractor.showUserSwitcher(context, expandable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/230830644): Replace View by an Expandable interface that can expand in either dialog
|
private fun onSettingsButtonClicked(expandable: Expandable) {
|
||||||
// or activity.
|
|
||||||
private fun onSettingsButtonClicked(view: View) {
|
|
||||||
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
footerActionsInteractor.showSettings(Expandable.fromView(view))
|
footerActionsInteractor.showSettings(expandable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onPowerButtonClicked(view: View) {
|
private fun onPowerButtonClicked(expandable: Expandable) {
|
||||||
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
footerActionsInteractor.showPowerMenuDialog(globalActionsDialogLite, view)
|
footerActionsInteractor.showPowerMenuDialog(globalActionsDialogLite, expandable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun userSwitcherButton(
|
private fun userSwitcherButton(
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ import android.content.DialogInterface.BUTTON_NEUTRAL
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import com.android.internal.jank.InteractionJankMonitor
|
import com.android.internal.jank.InteractionJankMonitor
|
||||||
import com.android.internal.logging.UiEventLogger
|
import com.android.internal.logging.UiEventLogger
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.animation.DialogCuj
|
import com.android.systemui.animation.DialogCuj
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator
|
import com.android.systemui.animation.DialogLaunchAnimator
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.plugins.FalsingManager
|
import com.android.systemui.plugins.FalsingManager
|
||||||
@@ -77,10 +77,10 @@ class UserSwitchDialogController @VisibleForTesting constructor(
|
|||||||
* Show a [UserDialog].
|
* Show a [UserDialog].
|
||||||
*
|
*
|
||||||
* Populate the dialog with information from and adapter obtained from
|
* Populate the dialog with information from and adapter obtained from
|
||||||
* [userDetailViewAdapterProvider] and show it as launched from [view].
|
* [userDetailViewAdapterProvider] and show it as launched from [expandable].
|
||||||
*/
|
*/
|
||||||
fun showDialog(view: View) {
|
fun showDialog(context: Context, expandable: Expandable) {
|
||||||
with(dialogFactory(view.context)) {
|
with(dialogFactory(context)) {
|
||||||
setShowForAllUsers(true)
|
setShowForAllUsers(true)
|
||||||
setCanceledOnTouchOutside(true)
|
setCanceledOnTouchOutside(true)
|
||||||
|
|
||||||
@@ -112,13 +112,19 @@ class UserSwitchDialogController @VisibleForTesting constructor(
|
|||||||
|
|
||||||
adapter.linkToViewGroup(gridFrame.findViewById(R.id.grid))
|
adapter.linkToViewGroup(gridFrame.findViewById(R.id.grid))
|
||||||
|
|
||||||
dialogLaunchAnimator.showFromView(
|
val controller =
|
||||||
this, view,
|
expandable.dialogLaunchController(
|
||||||
cuj = DialogCuj(
|
DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG)
|
||||||
InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
|
|
||||||
INTERACTION_JANK_TAG
|
|
||||||
)
|
)
|
||||||
|
if (controller != null) {
|
||||||
|
dialogLaunchAnimator.show(
|
||||||
|
this,
|
||||||
|
controller,
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
|
||||||
uiEventLogger.log(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN)
|
uiEventLogger.log(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN)
|
||||||
adapter.injectDialogShower(DialogShowerImpl(this, dialogLaunchAnimator))
|
adapter.injectDialogShower(DialogShowerImpl(this, dialogLaunchAnimator))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator;
|
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||||
|
import com.android.systemui.animation.Expandable;
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.flags.Flags;
|
import com.android.systemui.flags.Flags;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
@@ -67,7 +68,7 @@ public class MultiUserSwitchController extends ViewController<MultiUserSwitch> {
|
|||||||
ActivityLaunchAnimator.Controller.fromView(v, null),
|
ActivityLaunchAnimator.Controller.fromView(v, null),
|
||||||
true /* showOverlockscreenwhenlocked */, UserHandle.SYSTEM);
|
true /* showOverlockscreenwhenlocked */, UserHandle.SYSTEM);
|
||||||
} else {
|
} else {
|
||||||
mUserSwitchDialogController.showDialog(v);
|
mUserSwitchDialogController.showDialog(v.getContext(), Expandable.fromView(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone.userswitcher
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
import com.android.systemui.flags.Flags
|
import com.android.systemui.flags.Flags
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
@@ -75,7 +76,7 @@ class StatusBarUserSwitcherControllerImpl @Inject constructor(
|
|||||||
null /* ActivityLaunchAnimator.Controller */,
|
null /* ActivityLaunchAnimator.Controller */,
|
||||||
true /* showOverlockscreenwhenlocked */, UserHandle.SYSTEM)
|
true /* showOverlockscreenwhenlocked */, UserHandle.SYSTEM)
|
||||||
} else {
|
} else {
|
||||||
userSwitcherDialogController.showDialog(view)
|
userSwitcherDialogController.showDialog(view.context, Expandable.fromView(view))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import com.android.keyguard.KeyguardVisibilityHelper;
|
|||||||
import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
|
import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
|
||||||
import com.android.settingslib.drawable.CircleFramedDrawable;
|
import com.android.settingslib.drawable.CircleFramedDrawable;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.animation.Expandable;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
import com.android.systemui.plugins.FalsingManager;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
@@ -190,7 +191,8 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout>
|
|||||||
mUiEventLogger.log(
|
mUiEventLogger.log(
|
||||||
LockscreenGestureLogger.LockscreenUiEvent.LOCKSCREEN_SWITCH_USER_TAP);
|
LockscreenGestureLogger.LockscreenUiEvent.LOCKSCREEN_SWITCH_USER_TAP);
|
||||||
|
|
||||||
mUserSwitchDialogController.showDialog(mUserAvatarViewWithBackground);
|
mUserSwitchDialogController.showDialog(mUserAvatarViewWithBackground.getContext(),
|
||||||
|
Expandable.fromView(mUserAvatarViewWithBackground));
|
||||||
});
|
});
|
||||||
|
|
||||||
mUserAvatarView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
|
mUserAvatarView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import static junit.framework.Assert.assertNotNull;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
@@ -52,6 +51,7 @@ import android.text.SpannableStringBuilder;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
@@ -97,6 +97,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
private static final int DEFAULT_ICON_ID = R.drawable.ic_info_outline;
|
private static final int DEFAULT_ICON_ID = R.drawable.ic_info_outline;
|
||||||
|
|
||||||
private ViewGroup mRootView;
|
private ViewGroup mRootView;
|
||||||
|
private ViewGroup mSecurityFooterView;
|
||||||
private TextView mFooterText;
|
private TextView mFooterText;
|
||||||
private TestableImageView mPrimaryFooterIcon;
|
private TestableImageView mPrimaryFooterIcon;
|
||||||
private QSSecurityFooter mFooter;
|
private QSSecurityFooter mFooter;
|
||||||
@@ -121,21 +122,26 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
Looper looper = mTestableLooper.getLooper();
|
Looper looper = mTestableLooper.getLooper();
|
||||||
Handler mainHandler = new Handler(looper);
|
Handler mainHandler = new Handler(looper);
|
||||||
when(mUserTracker.getUserInfo()).thenReturn(mock(UserInfo.class));
|
when(mUserTracker.getUserInfo()).thenReturn(mock(UserInfo.class));
|
||||||
mRootView = (ViewGroup) new LayoutInflaterBuilder(mContext)
|
mSecurityFooterView = (ViewGroup) new LayoutInflaterBuilder(mContext)
|
||||||
.replace("ImageView", TestableImageView.class)
|
.replace("ImageView", TestableImageView.class)
|
||||||
.build().inflate(R.layout.quick_settings_security_footer, null, false);
|
.build().inflate(R.layout.quick_settings_security_footer, null, false);
|
||||||
mFooterUtils = new QSSecurityFooterUtils(getContext(),
|
mFooterUtils = new QSSecurityFooterUtils(getContext(),
|
||||||
getContext().getSystemService(DevicePolicyManager.class), mUserTracker,
|
getContext().getSystemService(DevicePolicyManager.class), mUserTracker,
|
||||||
mainHandler, mActivityStarter, mSecurityController, looper, mDialogLaunchAnimator);
|
mainHandler, mActivityStarter, mSecurityController, looper, mDialogLaunchAnimator);
|
||||||
mFooter = new QSSecurityFooter(mRootView, mainHandler, mSecurityController, looper,
|
mFooter = new QSSecurityFooter(mSecurityFooterView, mainHandler, mSecurityController,
|
||||||
mBroadcastDispatcher, mFooterUtils);
|
looper, mBroadcastDispatcher, mFooterUtils);
|
||||||
mFooterText = mRootView.findViewById(R.id.footer_text);
|
mFooterText = mSecurityFooterView.findViewById(R.id.footer_text);
|
||||||
mPrimaryFooterIcon = mRootView.findViewById(R.id.primary_footer_icon);
|
mPrimaryFooterIcon = mSecurityFooterView.findViewById(R.id.primary_footer_icon);
|
||||||
|
|
||||||
when(mSecurityController.getDeviceOwnerComponentOnAnyUser())
|
when(mSecurityController.getDeviceOwnerComponentOnAnyUser())
|
||||||
.thenReturn(DEVICE_OWNER_COMPONENT);
|
.thenReturn(DEVICE_OWNER_COMPONENT);
|
||||||
when(mSecurityController.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
|
when(mSecurityController.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
|
||||||
.thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
|
.thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
|
||||||
|
|
||||||
|
// mSecurityFooterView must have a ViewGroup parent so that
|
||||||
|
// DialogLaunchAnimator.Controller.fromView() does not return null.
|
||||||
|
mRootView = new FrameLayout(mContext);
|
||||||
|
mRootView.addView(mSecurityFooterView);
|
||||||
ViewUtils.attachView(mRootView);
|
ViewUtils.attachView(mRootView);
|
||||||
|
|
||||||
mFooter.init();
|
mFooter.init();
|
||||||
@@ -153,7 +159,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
mFooter.refreshState();
|
mFooter.refreshState();
|
||||||
|
|
||||||
TestableLooper.get(this).processAllMessages();
|
TestableLooper.get(this).processAllMessages();
|
||||||
assertEquals(View.GONE, mRootView.getVisibility());
|
assertEquals(View.GONE, mSecurityFooterView.getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -165,7 +171,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
TestableLooper.get(this).processAllMessages();
|
TestableLooper.get(this).processAllMessages();
|
||||||
assertEquals(mContext.getString(R.string.quick_settings_disclosure_management),
|
assertEquals(mContext.getString(R.string.quick_settings_disclosure_management),
|
||||||
mFooterText.getText());
|
mFooterText.getText());
|
||||||
assertEquals(View.VISIBLE, mRootView.getVisibility());
|
assertEquals(View.VISIBLE, mSecurityFooterView.getVisibility());
|
||||||
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
|
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
|
||||||
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
|
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
|
||||||
}
|
}
|
||||||
@@ -181,7 +187,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management,
|
assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management,
|
||||||
MANAGING_ORGANIZATION),
|
MANAGING_ORGANIZATION),
|
||||||
mFooterText.getText());
|
mFooterText.getText());
|
||||||
assertEquals(View.VISIBLE, mRootView.getVisibility());
|
assertEquals(View.VISIBLE, mSecurityFooterView.getVisibility());
|
||||||
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
|
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
|
||||||
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
|
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
|
||||||
}
|
}
|
||||||
@@ -200,7 +206,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
assertEquals(mContext.getString(
|
assertEquals(mContext.getString(
|
||||||
R.string.quick_settings_financed_disclosure_named_management,
|
R.string.quick_settings_financed_disclosure_named_management,
|
||||||
MANAGING_ORGANIZATION), mFooterText.getText());
|
MANAGING_ORGANIZATION), mFooterText.getText());
|
||||||
assertEquals(View.VISIBLE, mRootView.getVisibility());
|
assertEquals(View.VISIBLE, mSecurityFooterView.getVisibility());
|
||||||
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
|
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
|
||||||
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
|
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
|
||||||
}
|
}
|
||||||
@@ -217,7 +223,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
mFooter.refreshState();
|
mFooter.refreshState();
|
||||||
|
|
||||||
TestableLooper.get(this).processAllMessages();
|
TestableLooper.get(this).processAllMessages();
|
||||||
assertEquals(View.GONE, mRootView.getVisibility());
|
assertEquals(View.GONE, mSecurityFooterView.getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -227,8 +233,8 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
mFooter.refreshState();
|
mFooter.refreshState();
|
||||||
|
|
||||||
TestableLooper.get(this).processAllMessages();
|
TestableLooper.get(this).processAllMessages();
|
||||||
assertFalse(mRootView.isClickable());
|
assertFalse(mSecurityFooterView.isClickable());
|
||||||
assertEquals(View.GONE, mRootView.findViewById(R.id.footer_icon).getVisibility());
|
assertEquals(View.GONE, mSecurityFooterView.findViewById(R.id.footer_icon).getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -241,8 +247,9 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
mFooter.refreshState();
|
mFooter.refreshState();
|
||||||
|
|
||||||
TestableLooper.get(this).processAllMessages();
|
TestableLooper.get(this).processAllMessages();
|
||||||
assertTrue(mRootView.isClickable());
|
assertTrue(mSecurityFooterView.isClickable());
|
||||||
assertEquals(View.VISIBLE, mRootView.findViewById(R.id.footer_icon).getVisibility());
|
assertEquals(View.VISIBLE,
|
||||||
|
mSecurityFooterView.findViewById(R.id.footer_icon).getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -254,8 +261,8 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
mFooter.refreshState();
|
mFooter.refreshState();
|
||||||
|
|
||||||
TestableLooper.get(this).processAllMessages();
|
TestableLooper.get(this).processAllMessages();
|
||||||
assertFalse(mRootView.isClickable());
|
assertFalse(mSecurityFooterView.isClickable());
|
||||||
assertEquals(View.GONE, mRootView.findViewById(R.id.footer_icon).getVisibility());
|
assertEquals(View.GONE, mSecurityFooterView.findViewById(R.id.footer_icon).getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -734,11 +741,11 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testDialogUsesDialogLauncher() {
|
public void testDialogUsesDialogLauncher() {
|
||||||
when(mSecurityController.isDeviceManaged()).thenReturn(true);
|
when(mSecurityController.isDeviceManaged()).thenReturn(true);
|
||||||
mFooter.onClick(mRootView);
|
mFooter.onClick(mSecurityFooterView);
|
||||||
|
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
verify(mDialogLaunchAnimator).showFromView(any(), eq(mRootView), any());
|
verify(mDialogLaunchAnimator).show(any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -775,7 +782,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
ArgumentCaptor<AlertDialog> dialogCaptor = ArgumentCaptor.forClass(AlertDialog.class);
|
ArgumentCaptor<AlertDialog> dialogCaptor = ArgumentCaptor.forClass(AlertDialog.class);
|
||||||
|
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
verify(mDialogLaunchAnimator).showFromView(dialogCaptor.capture(), any(), any());
|
verify(mDialogLaunchAnimator).show(dialogCaptor.capture(), any());
|
||||||
|
|
||||||
AlertDialog dialog = dialogCaptor.getValue();
|
AlertDialog dialog = dialogCaptor.getValue();
|
||||||
dialog.create();
|
dialog.create();
|
||||||
@@ -817,8 +824,8 @@ public class QSSecurityFooterTest extends SysuiTestCase {
|
|||||||
verify(mBroadcastDispatcher).registerReceiverWithHandler(captor.capture(), any(), any(),
|
verify(mBroadcastDispatcher).registerReceiverWithHandler(captor.capture(), any(), any(),
|
||||||
any());
|
any());
|
||||||
|
|
||||||
// Pretend view is not visible temporarily
|
// Pretend view is not attached anymore.
|
||||||
mRootView.onVisibilityAggregated(false);
|
mRootView.removeView(mSecurityFooterView);
|
||||||
captor.getValue().onReceive(mContext,
|
captor.getValue().onReceive(mContext,
|
||||||
new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG));
|
new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG));
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ import android.os.UserHandle
|
|||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
import android.view.View
|
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.internal.logging.nano.MetricsProto
|
import com.android.internal.logging.nano.MetricsProto
|
||||||
import com.android.internal.logging.testing.FakeMetricsLogger
|
import com.android.internal.logging.testing.FakeMetricsLogger
|
||||||
import com.android.internal.logging.testing.UiEventLoggerFake
|
import com.android.internal.logging.testing.UiEventLoggerFake
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.flags.FakeFeatureFlags
|
import com.android.systemui.flags.FakeFeatureFlags
|
||||||
import com.android.systemui.flags.Flags
|
import com.android.systemui.flags.Flags
|
||||||
import com.android.systemui.globalactions.GlobalActionsDialogLite
|
import com.android.systemui.globalactions.GlobalActionsDialogLite
|
||||||
@@ -70,13 +70,13 @@ class FooterActionsInteractorTest : SysuiTestCase() {
|
|||||||
val underTest = utils.footerActionsInteractor(qsSecurityFooterUtils = qsSecurityFooterUtils)
|
val underTest = utils.footerActionsInteractor(qsSecurityFooterUtils = qsSecurityFooterUtils)
|
||||||
|
|
||||||
val quickSettingsContext = mock<Context>()
|
val quickSettingsContext = mock<Context>()
|
||||||
underTest.showDeviceMonitoringDialog(quickSettingsContext)
|
|
||||||
|
underTest.showDeviceMonitoringDialog(quickSettingsContext, null)
|
||||||
verify(qsSecurityFooterUtils).showDeviceMonitoringDialog(quickSettingsContext, null)
|
verify(qsSecurityFooterUtils).showDeviceMonitoringDialog(quickSettingsContext, null)
|
||||||
|
|
||||||
val view = mock<View>()
|
val expandable = mock<Expandable>()
|
||||||
whenever(view.context).thenReturn(quickSettingsContext)
|
underTest.showDeviceMonitoringDialog(quickSettingsContext, expandable)
|
||||||
underTest.showDeviceMonitoringDialog(view)
|
verify(qsSecurityFooterUtils).showDeviceMonitoringDialog(quickSettingsContext, expandable)
|
||||||
verify(qsSecurityFooterUtils).showDeviceMonitoringDialog(quickSettingsContext, null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -85,8 +85,8 @@ class FooterActionsInteractorTest : SysuiTestCase() {
|
|||||||
val underTest = utils.footerActionsInteractor(uiEventLogger = uiEventLogger)
|
val underTest = utils.footerActionsInteractor(uiEventLogger = uiEventLogger)
|
||||||
|
|
||||||
val globalActionsDialogLite = mock<GlobalActionsDialogLite>()
|
val globalActionsDialogLite = mock<GlobalActionsDialogLite>()
|
||||||
val view = mock<View>()
|
val expandable = mock<Expandable>()
|
||||||
underTest.showPowerMenuDialog(globalActionsDialogLite, view)
|
underTest.showPowerMenuDialog(globalActionsDialogLite, expandable)
|
||||||
|
|
||||||
// Event is logged.
|
// Event is logged.
|
||||||
val logs = uiEventLogger.logs
|
val logs = uiEventLogger.logs
|
||||||
@@ -99,7 +99,7 @@ class FooterActionsInteractorTest : SysuiTestCase() {
|
|||||||
.showOrHideDialog(
|
.showOrHideDialog(
|
||||||
/* keyguardShowing= */ false,
|
/* keyguardShowing= */ false,
|
||||||
/* isDeviceProvisioned= */ true,
|
/* isDeviceProvisioned= */ true,
|
||||||
view,
|
expandable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,11 +167,11 @@ class FooterActionsInteractorTest : SysuiTestCase() {
|
|||||||
userSwitchDialogController = userSwitchDialogController,
|
userSwitchDialogController = userSwitchDialogController,
|
||||||
)
|
)
|
||||||
|
|
||||||
val view = mock<View>()
|
val expandable = mock<Expandable>()
|
||||||
underTest.showUserSwitcher(view)
|
underTest.showUserSwitcher(context, expandable)
|
||||||
|
|
||||||
// Dialog is shown.
|
// Dialog is shown.
|
||||||
verify(userSwitchDialogController).showDialog(view)
|
verify(userSwitchDialogController).showDialog(context, expandable)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -184,12 +184,9 @@ class FooterActionsInteractorTest : SysuiTestCase() {
|
|||||||
activityStarter = activityStarter,
|
activityStarter = activityStarter,
|
||||||
)
|
)
|
||||||
|
|
||||||
// The clicked view. The context is necessary because it's used to build the intent, that
|
// The clicked expandable.
|
||||||
// we check below.
|
val expandable = mock<Expandable>()
|
||||||
val view = mock<View>()
|
underTest.showUserSwitcher(context, expandable)
|
||||||
whenever(view.context).thenReturn(context)
|
|
||||||
|
|
||||||
underTest.showUserSwitcher(view)
|
|
||||||
|
|
||||||
// Dialog is shown.
|
// Dialog is shown.
|
||||||
val intentCaptor = argumentCaptor<Intent>()
|
val intentCaptor = argumentCaptor<Intent>()
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ import android.content.DialogInterface
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.view.View
|
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.internal.logging.UiEventLogger
|
import com.android.internal.logging.UiEventLogger
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator
|
import com.android.systemui.animation.DialogLaunchAnimator
|
||||||
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.plugins.FalsingManager
|
import com.android.systemui.plugins.FalsingManager
|
||||||
import com.android.systemui.qs.PseudoGridView
|
import com.android.systemui.qs.PseudoGridView
|
||||||
@@ -35,6 +35,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialog
|
|||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
import com.android.systemui.util.mockito.capture
|
import com.android.systemui.util.mockito.capture
|
||||||
import com.android.systemui.util.mockito.eq
|
import com.android.systemui.util.mockito.eq
|
||||||
|
import com.android.systemui.util.mockito.mock
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -63,7 +64,7 @@ class UserSwitchDialogControllerTest : SysuiTestCase() {
|
|||||||
@Mock
|
@Mock
|
||||||
private lateinit var userDetailViewAdapter: UserDetailView.Adapter
|
private lateinit var userDetailViewAdapter: UserDetailView.Adapter
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var launchView: View
|
private lateinit var launchExpandable: Expandable
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var neutralButton: Button
|
private lateinit var neutralButton: Button
|
||||||
@Mock
|
@Mock
|
||||||
@@ -79,7 +80,6 @@ class UserSwitchDialogControllerTest : SysuiTestCase() {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
`when`(launchView.context).thenReturn(mContext)
|
|
||||||
`when`(dialog.context).thenReturn(mContext)
|
`when`(dialog.context).thenReturn(mContext)
|
||||||
|
|
||||||
controller = UserSwitchDialogController(
|
controller = UserSwitchDialogController(
|
||||||
@@ -94,32 +94,34 @@ class UserSwitchDialogControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun showDialog_callsDialogShow() {
|
fun showDialog_callsDialogShow() {
|
||||||
controller.showDialog(launchView)
|
val launchController = mock<DialogLaunchAnimator.Controller>()
|
||||||
verify(dialogLaunchAnimator).showFromView(eq(dialog), eq(launchView), any(), anyBoolean())
|
`when`(launchExpandable.dialogLaunchController(any())).thenReturn(launchController)
|
||||||
|
controller.showDialog(context, launchExpandable)
|
||||||
|
verify(dialogLaunchAnimator).show(eq(dialog), eq(launchController), anyBoolean())
|
||||||
verify(uiEventLogger).log(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN)
|
verify(uiEventLogger).log(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun dialog_showForAllUsers() {
|
fun dialog_showForAllUsers() {
|
||||||
controller.showDialog(launchView)
|
controller.showDialog(context, launchExpandable)
|
||||||
verify(dialog).setShowForAllUsers(true)
|
verify(dialog).setShowForAllUsers(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun dialog_cancelOnTouchOutside() {
|
fun dialog_cancelOnTouchOutside() {
|
||||||
controller.showDialog(launchView)
|
controller.showDialog(context, launchExpandable)
|
||||||
verify(dialog).setCanceledOnTouchOutside(true)
|
verify(dialog).setCanceledOnTouchOutside(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun adapterAndGridLinked() {
|
fun adapterAndGridLinked() {
|
||||||
controller.showDialog(launchView)
|
controller.showDialog(context, launchExpandable)
|
||||||
verify(userDetailViewAdapter).linkToViewGroup(any<PseudoGridView>())
|
verify(userDetailViewAdapter).linkToViewGroup(any<PseudoGridView>())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun doneButtonLogsCorrectly() {
|
fun doneButtonLogsCorrectly() {
|
||||||
controller.showDialog(launchView)
|
controller.showDialog(context, launchExpandable)
|
||||||
|
|
||||||
verify(dialog).setPositiveButton(anyInt(), capture(clickCaptor))
|
verify(dialog).setPositiveButton(anyInt(), capture(clickCaptor))
|
||||||
|
|
||||||
@@ -132,7 +134,7 @@ class UserSwitchDialogControllerTest : SysuiTestCase() {
|
|||||||
fun clickSettingsButton_noFalsing_opensSettings() {
|
fun clickSettingsButton_noFalsing_opensSettings() {
|
||||||
`when`(falsingManager.isFalseTap(anyInt())).thenReturn(false)
|
`when`(falsingManager.isFalseTap(anyInt())).thenReturn(false)
|
||||||
|
|
||||||
controller.showDialog(launchView)
|
controller.showDialog(context, launchExpandable)
|
||||||
|
|
||||||
verify(dialog)
|
verify(dialog)
|
||||||
.setNeutralButton(anyInt(), capture(clickCaptor), eq(false) /* dismissOnClick */)
|
.setNeutralButton(anyInt(), capture(clickCaptor), eq(false) /* dismissOnClick */)
|
||||||
@@ -153,7 +155,7 @@ class UserSwitchDialogControllerTest : SysuiTestCase() {
|
|||||||
fun clickSettingsButton_Falsing_notOpensSettings() {
|
fun clickSettingsButton_Falsing_notOpensSettings() {
|
||||||
`when`(falsingManager.isFalseTap(anyInt())).thenReturn(true)
|
`when`(falsingManager.isFalseTap(anyInt())).thenReturn(true)
|
||||||
|
|
||||||
controller.showDialog(launchView)
|
controller.showDialog(context, launchExpandable)
|
||||||
|
|
||||||
verify(dialog)
|
verify(dialog)
|
||||||
.setNeutralButton(anyInt(), capture(clickCaptor), eq(false) /* dismissOnClick */)
|
.setNeutralButton(anyInt(), capture(clickCaptor), eq(false) /* dismissOnClick */)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import android.content.Intent
|
|||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
import android.view.View
|
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
@@ -34,8 +33,8 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.verify
|
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@@ -91,7 +90,7 @@ class StatusBarUserSwitcherControllerOldImplTest : SysuiTestCase() {
|
|||||||
fun testStartActivity() {
|
fun testStartActivity() {
|
||||||
`when`(featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)).thenReturn(false)
|
`when`(featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)).thenReturn(false)
|
||||||
statusBarUserSwitcherContainer.callOnClick()
|
statusBarUserSwitcherContainer.callOnClick()
|
||||||
verify(userSwitcherDialogController).showDialog(any(View::class.java))
|
verify(userSwitcherDialogController).showDialog(any(), any())
|
||||||
`when`(featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)).thenReturn(true)
|
`when`(featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)).thenReturn(true)
|
||||||
statusBarUserSwitcherContainer.callOnClick()
|
statusBarUserSwitcherContainer.callOnClick()
|
||||||
verify(activityStarter).startActivity(any(Intent::class.java),
|
verify(activityStarter).startActivity(any(Intent::class.java),
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.systemui.qs
|
package com.android.systemui.qs
|
||||||
|
|
||||||
import android.view.View
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.qs.FgsManagerController.OnDialogDismissedListener
|
import com.android.systemui.qs.FgsManagerController.OnDialogDismissedListener
|
||||||
import com.android.systemui.qs.FgsManagerController.OnNumberOfPackagesChangedListener
|
import com.android.systemui.qs.FgsManagerController.OnNumberOfPackagesChangedListener
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@@ -54,7 +54,7 @@ class FakeFgsManagerController(
|
|||||||
|
|
||||||
override fun init() {}
|
override fun init() {}
|
||||||
|
|
||||||
override fun showDialog(viewLaunchedFrom: View?) {}
|
override fun showDialog(expandable: Expandable?) {}
|
||||||
|
|
||||||
override fun addOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener) {
|
override fun addOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener) {
|
||||||
numRunningPackagesListeners.add(listener)
|
numRunningPackagesListeners.add(listener)
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ import com.android.systemui.statusbar.policy.UserSwitcherController
|
|||||||
import com.android.systemui.util.mockito.mock
|
import com.android.systemui.util.mockito.mock
|
||||||
import com.android.systemui.util.settings.FakeSettings
|
import com.android.systemui.util.settings.FakeSettings
|
||||||
import com.android.systemui.util.settings.GlobalSettings
|
import com.android.systemui.util.settings.GlobalSettings
|
||||||
import com.android.systemui.util.time.FakeSystemClock
|
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||||
|
|
||||||
@@ -68,7 +67,6 @@ import kotlinx.coroutines.test.TestCoroutineDispatcher
|
|||||||
class FooterActionsTestUtils(
|
class FooterActionsTestUtils(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val testableLooper: TestableLooper,
|
private val testableLooper: TestableLooper,
|
||||||
private val fakeClock: FakeSystemClock = FakeSystemClock(),
|
|
||||||
) {
|
) {
|
||||||
/** Enable or disable the user switcher in the settings. */
|
/** Enable or disable the user switcher in the settings. */
|
||||||
fun setUserSwitcherEnabled(settings: GlobalSettings, enabled: Boolean, userId: Int) {
|
fun setUserSwitcherEnabled(settings: GlobalSettings, enabled: Boolean, userId: Int) {
|
||||||
|
|||||||
Reference in New Issue
Block a user