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