Merge changes Ide7d63a7,I9e075f29 into tm-qpr-dev am: 337e5497e7

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21565287

Change-Id: I1f30d87947157b091dae4d5f5672fe1ee8055f03
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2023-03-01 23:02:05 +00:00
committed by Automerger Merge Worker
94 changed files with 344 additions and 242 deletions

View File

@@ -26,7 +26,7 @@ interface Expandable {
* currently not attached or visible). * currently not attached or visible).
* *
* @param cujType the CUJ type from the [com.android.internal.jank.InteractionJankMonitor] * @param cujType the CUJ type from the [com.android.internal.jank.InteractionJankMonitor]
* associated to the launch that will use this controller. * associated to the launch that will use this controller.
*/ */
fun activityLaunchController(cujType: Int? = null): ActivityLaunchAnimator.Controller? fun activityLaunchController(cujType: Int? = null): ActivityLaunchAnimator.Controller?

View File

@@ -75,7 +75,7 @@ class LaunchAnimator(private val timings: Timings, private val interpolators: In
* - Get the associated [Context]. * - Get the associated [Context].
* - Compute whether we are expanding fully above the launch container. * - Compute whether we are expanding fully above the launch container.
* - Get to overlay to which we initially put the window background layer, until the opening * - Get to overlay to which we initially put the window background layer, until the opening
* window is made visible (see [openingWindowSyncView]). * window is made visible (see [openingWindowSyncView]).
* *
* This container can be changed to force this [Controller] to animate the expanding view * This container can be changed to force this [Controller] to animate the expanding view
* inside a different location, for instance to ensure correct layering during the * inside a different location, for instance to ensure correct layering during the

View File

@@ -24,7 +24,7 @@ interface LaunchableView {
* Set whether this view should block/postpone all calls to [View.setVisibility]. This ensures * Set whether this view should block/postpone all calls to [View.setVisibility]. This ensures
* that this view: * that this view:
* - remains invisible during the launch animation given that it is ghosted and already drawn * - remains invisible during the launch animation given that it is ghosted and already drawn
* somewhere else. * somewhere else.
* - remains invisible as long as a dialog expanded from it is shown. * - remains invisible as long as a dialog expanded from it is shown.
* - restores its expected visibility once the dialog expanded from it is dismissed. * - restores its expected visibility once the dialog expanded from it is dismissed.
* *

View File

@@ -182,9 +182,9 @@ class RemoteTransitionAdapter {
* Represents a TransitionInfo object as an array of old-style targets * Represents a TransitionInfo object as an array of old-style targets
* *
* @param wallpapers If true, this will return wallpaper targets; otherwise it returns * @param wallpapers If true, this will return wallpaper targets; otherwise it returns
* non-wallpaper targets. * non-wallpaper targets.
* @param leashMap Temporary map of change leash -> launcher leash. Is an output, so should * @param leashMap Temporary map of change leash -> launcher leash. Is an output, so should
* be populated by this function. If null, it is ignored. * be populated by this function. If null, it is ignored.
*/ */
fun wrapTargets( fun wrapTargets(
info: TransitionInfo, info: TransitionInfo,

View File

@@ -6,6 +6,7 @@ object ShadeInterpolation {
/** /**
* Interpolate alpha for notification background scrim during shade expansion. * Interpolate alpha for notification background scrim during shade expansion.
*
* @param fraction Shade expansion fraction * @param fraction Shade expansion fraction
*/ */
@JvmStatic @JvmStatic
@@ -16,6 +17,7 @@ object ShadeInterpolation {
/** /**
* Interpolate alpha for shade content during shade expansion. * Interpolate alpha for shade content during shade expansion.
*
* @param fraction Shade expansion fraction * @param fraction Shade expansion fraction
*/ */
@JvmStatic @JvmStatic

View File

@@ -161,7 +161,6 @@ class TextInterpolator(layout: Layout) {
* This API is useful to continue animation from the middle of the state. For example, if you * This API is useful to continue animation from the middle of the state. For example, if you
* animate weight from 200 to 400, then if you want to move back to 200 at the half of the * animate weight from 200 to 400, then if you want to move back to 200 at the half of the
* animation, it will look like * animation, it will look like
*
* <pre> <code> * <pre> <code>
* ``` * ```
* val interp = TextInterpolator(layout) * val interp = TextInterpolator(layout)
@@ -497,7 +496,9 @@ class TextInterpolator(layout: Layout) {
count, count,
layout.textDirectionHeuristic, layout.textDirectionHeuristic,
paint paint
) { _, _, glyphs, _ -> runs.add(glyphs) } ) { _, _, glyphs, _ ->
runs.add(glyphs)
}
out.add(runs) out.add(runs)
if (lineNo > 0) { if (lineNo > 0) {

View File

@@ -25,7 +25,6 @@ import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
/** /**
* Shader class that renders an expanding ripple effect. The ripple contains three elements: * Shader class that renders an expanding ripple effect. The ripple contains three elements:
*
* 1. an expanding filled [RippleShape] that appears in the beginning and quickly fades away * 1. an expanding filled [RippleShape] that appears in the beginning and quickly fades away
* 2. an expanding ring that appears throughout the effect * 2. an expanding ring that appears throughout the effect
* 3. an expanding ring-shaped area that reveals noise over #2. * 3. an expanding ring-shaped area that reveals noise over #2.
@@ -311,6 +310,7 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
* Parameters used for fade in and outs of the ripple. * Parameters used for fade in and outs of the ripple.
* *
* <p>Note that all the fade in/ outs are "linear" progression. * <p>Note that all the fade in/ outs are "linear" progression.
*
* ``` * ```
* (opacity) * (opacity)
* 1 * 1
@@ -325,6 +325,7 @@ class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
* fadeIn fadeOut * fadeIn fadeOut
* Start & End Start & End * Start & End Start & End
* ``` * ```
*
* <p>If no fade in/ out is needed, set [fadeInStart] and [fadeInEnd] to 0; [fadeOutStart] and * <p>If no fade in/ out is needed, set [fadeInStart] and [fadeInEnd] to 0; [fadeOutStart] and
* [fadeOutEnd] to 1. * [fadeOutEnd] to 1.
*/ */

View File

@@ -30,12 +30,14 @@ data class TurbulenceNoiseAnimationConfig(
* Noise move speed variables. * Noise move speed variables.
* *
* Its sign determines the direction; magnitude determines the speed. <ul> * Its sign determines the direction; magnitude determines the speed. <ul>
*
* ``` * ```
* <li> [noiseMoveSpeedX] positive: right to left; negative: left to right. * <li> [noiseMoveSpeedX] positive: right to left; negative: left to right.
* <li> [noiseMoveSpeedY] positive: bottom to top; negative: top to bottom. * <li> [noiseMoveSpeedY] positive: bottom to top; negative: top to bottom.
* <li> [noiseMoveSpeedZ] its sign doesn't matter much, as it moves in Z direction. Use it * <li> [noiseMoveSpeedZ] its sign doesn't matter much, as it moves in Z direction. Use it
* to add turbulence in place. * to add turbulence in place.
* ``` * ```
*
* </ul> * </ul>
*/ */
val noiseMoveSpeedX: Float = 0f, val noiseMoveSpeedX: Float = 0f,

View File

@@ -64,7 +64,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
class BadClass( class BadClass(
private val viewModel: ViewModel, private val viewModel: ViewModel,
) )
""".trimIndent() """
.trimIndent()
) )
) )
.issues( .issues(
@@ -98,7 +99,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
class BadClass( class BadClass(
private val repository: Repository, private val repository: Repository,
) )
""".trimIndent() """
.trimIndent()
) )
) )
.issues( .issues(
@@ -136,7 +138,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
private val interactor: Interactor, private val interactor: Interactor,
private val viewmodel: ViewModel, private val viewmodel: ViewModel,
) )
""".trimIndent() """
.trimIndent()
) )
) )
.issues( .issues(
@@ -176,7 +179,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
class BadClass( class BadClass(
private val interactor: Interactor, private val interactor: Interactor,
) )
""".trimIndent() """
.trimIndent()
) )
) )
.issues( .issues(
@@ -207,7 +211,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
data class Model( data class Model(
private val name: String, private val name: String,
) )
""".trimIndent() """
.trimIndent()
) )
private val REPOSITORY_FILE = private val REPOSITORY_FILE =
TestFiles.kotlin( TestFiles.kotlin(
@@ -228,7 +233,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
return models return models
} }
} }
""".trimIndent() """
.trimIndent()
) )
private val INTERACTOR_FILE = private val INTERACTOR_FILE =
TestFiles.kotlin( TestFiles.kotlin(
@@ -245,7 +251,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
return repository.getModels() return repository.getModels()
} }
} }
""".trimIndent() """
.trimIndent()
) )
private val VIEW_MODEL_FILE = private val VIEW_MODEL_FILE =
TestFiles.kotlin( TestFiles.kotlin(
@@ -262,7 +269,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
return interactor.getModels().map { model -> model.name } return interactor.getModels().map { model -> model.name }
} }
} }
""".trimIndent() """
.trimIndent()
) )
private val NON_CLEAN_ARCHITECTURE_FILE = private val NON_CLEAN_ARCHITECTURE_FILE =
TestFiles.kotlin( TestFiles.kotlin(
@@ -282,7 +290,8 @@ class CleanArchitectureDependencyViolationDetectorTest : SystemUILintDetectorTes
) )
} }
} }
""".trimIndent() """
.trimIndent()
) )
private val LEGITIMATE_FILES = private val LEGITIMATE_FILES =
arrayOf( arrayOf(

View File

@@ -37,7 +37,8 @@ class DumpableNotRegisteredDetectorTest : SystemUILintDetectorTest() {
class SomeClass() { class SomeClass() {
} }
""".trimIndent() """
.trimIndent()
), ),
*stubs, *stubs,
) )
@@ -67,7 +68,8 @@ class DumpableNotRegisteredDetectorTest : SystemUILintDetectorTest() {
pw.println("testDump"); pw.println("testDump");
} }
} }
""".trimIndent() """
.trimIndent()
), ),
*stubs, *stubs,
) )
@@ -97,7 +99,8 @@ class DumpableNotRegisteredDetectorTest : SystemUILintDetectorTest() {
pw.println("testDump"); pw.println("testDump");
} }
} }
""".trimIndent() """
.trimIndent()
), ),
*stubs, *stubs,
) )
@@ -127,7 +130,8 @@ class DumpableNotRegisteredDetectorTest : SystemUILintDetectorTest() {
pw.println("testDump"); pw.println("testDump");
} }
} }
""".trimIndent() """
.trimIndent()
), ),
*stubs, *stubs,
) )

View File

@@ -78,11 +78,10 @@ interface SystemUiController {
* Set the status bar color. * Set the status bar color.
* *
* @param color The **desired** [Color] to set. This may require modification if running on an * @param color The **desired** [Color] to set. This may require modification if running on an
* API level that only supports white status bar icons. * API level that only supports white status bar icons.
* @param darkIcons Whether dark status bar icons would be preferable. * @param darkIcons Whether dark status bar icons would be preferable.
* @param transformColorForLightContent A lambda which will be invoked to transform [color] if * @param transformColorForLightContent A lambda which will be invoked to transform [color] if
* dark icons were requested but are not available. Defaults to applying a black scrim. * dark icons were requested but are not available. Defaults to applying a black scrim.
*
* @see statusBarDarkContentEnabled * @see statusBarDarkContentEnabled
*/ */
fun setStatusBarColor( fun setStatusBarColor(
@@ -95,16 +94,15 @@ interface SystemUiController {
* Set the navigation bar color. * Set the navigation bar color.
* *
* @param color The **desired** [Color] to set. This may require modification if running on an * @param color The **desired** [Color] to set. This may require modification if running on an
* API level that only supports white navigation bar icons. Additionally this will be ignored * API level that only supports white navigation bar icons. Additionally this will be ignored
* and [Color.Transparent] will be used on API 29+ where gesture navigation is preferred or the * and [Color.Transparent] will be used on API 29+ where gesture navigation is preferred or
* system UI automatically applies background protection in other navigation modes. * the system UI automatically applies background protection in other navigation modes.
* @param darkIcons Whether dark navigation bar icons would be preferable. * @param darkIcons Whether dark navigation bar icons would be preferable.
* @param navigationBarContrastEnforced Whether the system should ensure that the navigation bar * @param navigationBarContrastEnforced Whether the system should ensure that the navigation bar
* has enough contrast when a fully transparent background is requested. Only supported on API * has enough contrast when a fully transparent background is requested. Only supported on API
* 29+. * 29+.
* @param transformColorForLightContent A lambda which will be invoked to transform [color] if * @param transformColorForLightContent A lambda which will be invoked to transform [color] if
* dark icons were requested but are not available. Defaults to applying a black scrim. * dark icons were requested but are not available. Defaults to applying a black scrim.
*
* @see navigationBarDarkContentEnabled * @see navigationBarDarkContentEnabled
* @see navigationBarContrastEnforced * @see navigationBarContrastEnforced
*/ */

View File

@@ -255,7 +255,9 @@ fun Expandable(
.onGloballyPositioned { .onGloballyPositioned {
controller.boundsInComposeViewRoot.value = it.boundsInRoot() controller.boundsInComposeViewRoot.value = it.boundsInRoot()
} }
) { wrappedContent(controller.expandable) } ) {
wrappedContent(controller.expandable)
}
} }
else -> { else -> {
val clickModifier = val clickModifier =

View File

@@ -156,9 +156,9 @@ internal class ExpandableControllerImpl(
* Create a [LaunchAnimator.Controller] that is going to be used to drive an activity or dialog * Create a [LaunchAnimator.Controller] that is going to be used to drive an activity or dialog
* animation. This controller will: * animation. This controller will:
* 1. Compute the start/end animation state using [boundsInComposeViewRoot] and the location of * 1. Compute the start/end animation state using [boundsInComposeViewRoot] and the location of
* composeViewRoot on the screen. * composeViewRoot on the screen.
* 2. Update [animatorState] with the current animation state if we are animating, or null * 2. Update [animatorState] with the current animation state if we are animating, or null
* otherwise. * otherwise.
*/ */
private fun launchController(): LaunchAnimator.Controller { private fun launchController(): LaunchAnimator.Controller {
return object : LaunchAnimator.Controller { return object : LaunchAnimator.Controller {

View File

@@ -86,21 +86,20 @@ object PagerDefaults {
/** /**
* A horizontally scrolling layout that allows users to flip between items to the left and right. * A horizontally scrolling layout that allows users to flip between items to the left and right.
* *
* @sample com.google.accompanist.sample.pager.HorizontalPagerSample
*
* @param count the number of pages. * @param count the number of pages.
* @param modifier the modifier to apply to this layout. * @param modifier the modifier to apply to this layout.
* @param state the state object to be used to control or observe the pager's state. * @param state the state object to be used to control or observe the pager's state.
* @param reverseLayout reverse the direction of scrolling and layout, when `true` items will be * @param reverseLayout reverse the direction of scrolling and layout, when `true` items will be
* composed from the end to the start and [PagerState.currentPage] == 0 will mean the first item is * composed from the end to the start and [PagerState.currentPage] == 0 will mean the first item
* located at the end. * is located at the end.
* @param itemSpacing horizontal spacing to add between items. * @param itemSpacing horizontal spacing to add between items.
* @param flingBehavior logic describing fling behavior. * @param flingBehavior logic describing fling behavior.
* @param key the scroll position will be maintained based on the key, which means if you add/remove * @param key the scroll position will be maintained based on the key, which means if you add/remove
* items before the current visible item the item with the given key will be kept as the first * items before the current visible item the item with the given key will be kept as the first
* visible one. * visible one.
* @param content a block which describes the content. Inside this block you can reference * @param content a block which describes the content. Inside this block you can reference
* [PagerScope.currentPage] and other properties in [PagerScope]. * [PagerScope.currentPage] and other properties in [PagerScope].
* @sample com.google.accompanist.sample.pager.HorizontalPagerSample
*/ */
@ExperimentalPagerApi @ExperimentalPagerApi
@Composable @Composable
@@ -134,21 +133,20 @@ fun HorizontalPager(
/** /**
* A vertically scrolling layout that allows users to flip between items to the top and bottom. * A vertically scrolling layout that allows users to flip between items to the top and bottom.
* *
* @sample com.google.accompanist.sample.pager.VerticalPagerSample
*
* @param count the number of pages. * @param count the number of pages.
* @param modifier the modifier to apply to this layout. * @param modifier the modifier to apply to this layout.
* @param state the state object to be used to control or observe the pager's state. * @param state the state object to be used to control or observe the pager's state.
* @param reverseLayout reverse the direction of scrolling and layout, when `true` items will be * @param reverseLayout reverse the direction of scrolling and layout, when `true` items will be
* composed from the bottom to the top and [PagerState.currentPage] == 0 will mean the first item is * composed from the bottom to the top and [PagerState.currentPage] == 0 will mean the first item
* located at the bottom. * is located at the bottom.
* @param itemSpacing vertical spacing to add between items. * @param itemSpacing vertical spacing to add between items.
* @param flingBehavior logic describing fling behavior. * @param flingBehavior logic describing fling behavior.
* @param key the scroll position will be maintained based on the key, which means if you add/remove * @param key the scroll position will be maintained based on the key, which means if you add/remove
* items before the current visible item the item with the given key will be kept as the first * items before the current visible item the item with the given key will be kept as the first
* visible one. * visible one.
* @param content a block which describes the content. Inside this block you can reference * @param content a block which describes the content. Inside this block you can reference
* [PagerScope.currentPage] and other properties in [PagerScope]. * [PagerScope.currentPage] and other properties in [PagerScope].
* @sample com.google.accompanist.sample.pager.VerticalPagerSample
*/ */
@ExperimentalPagerApi @ExperimentalPagerApi
@Composable @Composable
@@ -246,7 +244,9 @@ internal fun Pager(
// Constraint the content to be <= than the size of the pager. // Constraint the content to be <= than the size of the pager.
.fillParentMaxHeight() .fillParentMaxHeight()
.wrapContentSize() .wrapContentSize()
) { pagerScope.content(page) } ) {
pagerScope.content(page)
}
} }
} }
} else { } else {
@@ -272,7 +272,9 @@ internal fun Pager(
// Constraint the content to be <= than the size of the pager. // Constraint the content to be <= than the size of the pager.
.fillParentMaxWidth() .fillParentMaxWidth()
.wrapContentSize() .wrapContentSize()
) { pagerScope.content(page) } ) {
pagerScope.content(page)
}
} }
} }
} }

View File

@@ -198,7 +198,7 @@ class PagerState(
* *
* @param page the page to animate to. Must be between 0 and [pageCount] (inclusive). * @param page the page to animate to. Must be between 0 and [pageCount] (inclusive).
* @param pageOffset the percentage of the page width to offset, from the start of [page]. Must * @param pageOffset the percentage of the page width to offset, from the start of [page]. Must
* be in the range 0f..1f. * be in the range 0f..1f.
*/ */
suspend fun animateScrollToPage( suspend fun animateScrollToPage(
@IntRange(from = 0) page: Int, @IntRange(from = 0) page: Int,

View File

@@ -44,11 +44,11 @@ internal object SnappingFlingBehaviorDefaults {
/** /**
* Create and remember a snapping [FlingBehavior] to be used with [LazyListState]. * Create and remember a snapping [FlingBehavior] to be used with [LazyListState].
* *
* TODO: move this to a new module and make it public
*
* @param lazyListState The [LazyListState] to update. * @param lazyListState The [LazyListState] to update.
* @param decayAnimationSpec The decay animation spec to use for decayed flings. * @param decayAnimationSpec The decay animation spec to use for decayed flings.
* @param snapAnimationSpec The animation spec to use when snapping. * @param snapAnimationSpec The animation spec to use when snapping.
*
* TODO: move this to a new module and make it public
*/ */
@Composable @Composable
internal fun rememberSnappingFlingBehavior( internal fun rememberSnappingFlingBehavior(

View File

@@ -60,7 +60,7 @@ import com.android.systemui.people.ui.viewmodel.PeopleViewModel
* *
* @param viewModel the [PeopleViewModel] that should be composed. * @param viewModel the [PeopleViewModel] that should be composed.
* @param onResult the callback called with the result of this screen. Callers should usually finish * @param onResult the callback called with the result of this screen. Callers should usually finish
* the Activity/Fragment/View hosting this Composable once a result is available. * the Activity/Fragment/View hosting this Composable once a result is available.
*/ */
@Composable @Composable
fun PeopleScreen( fun PeopleScreen(

View File

@@ -79,7 +79,9 @@ internal fun PeopleScreenEmpty(
containerColor = androidColors.colorAccentPrimary, containerColor = androidColors.colorAccentPrimary,
contentColor = androidColors.textColorOnAccent, contentColor = androidColors.textColorOnAccent,
) )
) { Text(stringResource(R.string.got_it)) } ) {
Text(stringResource(R.string.got_it))
}
} }
} }

View File

@@ -51,7 +51,7 @@ object CustomizationProviderContract {
* *
* Supported operations: * Supported operations:
* - Query - to know which slots are available, query the [SlotTable.URI] [Uri]. The result * - Query - to know which slots are available, query the [SlotTable.URI] [Uri]. The result
* set will contain rows with the [SlotTable.Columns] columns. * set will contain rows with the [SlotTable.Columns] columns.
*/ */
object SlotTable { object SlotTable {
const val TABLE_NAME = "slots" const val TABLE_NAME = "slots"
@@ -74,8 +74,8 @@ object CustomizationProviderContract {
* *
* Supported operations: * Supported operations:
* - Query - to know about all the affordances that are available on the device, regardless * - Query - to know about all the affordances that are available on the device, regardless
* of which ones are currently selected, query the [AffordanceTable.URI] [Uri]. The result * of which ones are currently selected, query the [AffordanceTable.URI] [Uri]. The result
* set will contain rows, each with the columns specified in [AffordanceTable.Columns]. * set will contain rows, each with the columns specified in [AffordanceTable.Columns].
*/ */
object AffordanceTable { object AffordanceTable {
const val TABLE_NAME = "affordances" const val TABLE_NAME = "affordances"
@@ -128,14 +128,14 @@ object CustomizationProviderContract {
* *
* Supported operations: * Supported operations:
* - Insert - to insert an affordance and place it in a slot, insert values for the columns * - Insert - to insert an affordance and place it in a slot, insert values for the columns
* into the [SelectionTable.URI] [Uri]. The maximum capacity rule is enforced by the system. * into the [SelectionTable.URI] [Uri]. The maximum capacity rule is enforced by the
* Selecting a new affordance for a slot that is already full will automatically remove the * system. Selecting a new affordance for a slot that is already full will automatically
* oldest affordance from the slot. * remove the oldest affordance from the slot.
* - Query - to know which affordances are set on which slots, query the * - Query - to know which affordances are set on which slots, query the
* [SelectionTable.URI] [Uri]. The result set will contain rows, each of which with the * [SelectionTable.URI] [Uri]. The result set will contain rows, each of which with the
* columns from [SelectionTable.Columns]. * columns from [SelectionTable.Columns].
* - Delete - to unselect an affordance, removing it from a slot, delete from the * - Delete - to unselect an affordance, removing it from a slot, delete from the
* [SelectionTable.URI] [Uri], passing in values for each column. * [SelectionTable.URI] [Uri], passing in values for each column.
*/ */
object SelectionTable { object SelectionTable {
const val TABLE_NAME = "selections" const val TABLE_NAME = "selections"
@@ -160,7 +160,7 @@ object CustomizationProviderContract {
* *
* Supported operations: * Supported operations:
* - Query - to know the values of flags, query the [FlagsTable.URI] [Uri]. The result set will * - Query - to know the values of flags, query the [FlagsTable.URI] [Uri]. The result set will
* contain rows, each of which with the columns from [FlagsTable.Columns]. * contain rows, each of which with the columns from [FlagsTable.Columns].
*/ */
object FlagsTable { object FlagsTable {
const val TABLE_NAME = "flags" const val TABLE_NAME = "flags"

View File

@@ -35,7 +35,6 @@ import kotlin.math.max
* as the result of taking a bug report). * as the result of taking a bug report).
* *
* You can dump the entire buffer at any time by running: * You can dump the entire buffer at any time by running:
*
* ``` * ```
* $ adb shell dumpsys activity service com.android.systemui/.SystemUIService <bufferName> * $ adb shell dumpsys activity service com.android.systemui/.SystemUIService <bufferName>
* ``` * ```
@@ -46,13 +45,11 @@ import kotlin.math.max
* locally (usually for debugging purposes). * locally (usually for debugging purposes).
* *
* To enable logcat echoing for an entire buffer: * To enable logcat echoing for an entire buffer:
*
* ``` * ```
* $ adb shell settings put global systemui/buffer/<bufferName> <level> * $ adb shell settings put global systemui/buffer/<bufferName> <level>
* ``` * ```
* *
* To enable logcat echoing for a specific tag: * To enable logcat echoing for a specific tag:
*
* ``` * ```
* $ adb shell settings put global systemui/tag/<tag> <level> * $ adb shell settings put global systemui/tag/<tag> <level>
* ``` * ```
@@ -64,10 +61,10 @@ import kotlin.math.max
* LogBufferFactory. * LogBufferFactory.
* *
* @param name The name of this buffer, printed when the buffer is dumped and in some other * @param name The name of this buffer, printed when the buffer is dumped and in some other
* situations. * situations.
* @param maxSize The maximum number of messages to keep in memory at any one time. Buffers start * @param maxSize The maximum number of messages to keep in memory at any one time. Buffers start
* out empty and grow up to [maxSize] as new messages are logged. Once the buffer's size reaches the * out empty and grow up to [maxSize] as new messages are logged. Once the buffer's size reaches
* maximum, it behaves like a ring buffer. * the maximum, it behaves like a ring buffer.
*/ */
class LogBuffer class LogBuffer
@JvmOverloads @JvmOverloads
@@ -116,22 +113,22 @@ constructor(
* initializer stored and converts it to a human-readable log message. * initializer stored and converts it to a human-readable log message.
* *
* @param tag A string of at most 23 characters, used for grouping logs into categories or * @param tag A string of at most 23 characters, used for grouping logs into categories or
* subjects. If this message is echoed to logcat, this will be the tag that is used. * subjects. If this message is echoed to logcat, this will be the tag that is used.
* @param level Which level to log the message at, both to the buffer and to logcat if it's * @param level Which level to log the message at, both to the buffer and to logcat if it's
* echoed. In general, a module should split most of its logs into either INFO or DEBUG level. * echoed. In general, a module should split most of its logs into either INFO or DEBUG level.
* INFO level should be reserved for information that other parts of the system might care * INFO level should be reserved for information that other parts of the system might care
* about, leaving the specifics of code's day-to-day operations to DEBUG. * about, leaving the specifics of code's day-to-day operations to DEBUG.
* @param messageInitializer A function that will be called immediately to store relevant data * @param messageInitializer A function that will be called immediately to store relevant data
* on the log message. The value of `this` will be the LogMessage to be initialized. * on the log message. The value of `this` will be the LogMessage to be initialized.
* @param messagePrinter A function that will be called if and when the message needs to be * @param messagePrinter A function that will be called if and when the message needs to be
* dumped to logcat or a bug report. It should read the data stored by the initializer and * dumped to logcat or a bug report. It should read the data stored by the initializer and
* convert it to a human-readable string. The value of `this` will be the LogMessage to be * convert it to a human-readable string. The value of `this` will be the LogMessage to be
* printed. **IMPORTANT:** The printer should ONLY ever reference fields on the LogMessage and * printed. **IMPORTANT:** The printer should ONLY ever reference fields on the LogMessage and
* NEVER any variables in its enclosing scope. Otherwise, the runtime will need to allocate a * NEVER any variables in its enclosing scope. Otherwise, the runtime will need to allocate a
* new instance of the printer for each call, thwarting our attempts at avoiding any sort of * new instance of the printer for each call, thwarting our attempts at avoiding any sort of
* allocation. * allocation.
* @param exception Provide any exception that need to be logged. This is saved as * @param exception Provide any exception that need to be logged. This is saved as
* [LogMessage.exception] * [LogMessage.exception]
*/ */
@JvmOverloads @JvmOverloads
inline fun log( inline fun log(

View File

@@ -28,7 +28,6 @@ import android.provider.Settings
* Version of [LogcatEchoTracker] for debuggable builds * Version of [LogcatEchoTracker] for debuggable builds
* *
* The log level of individual buffers or tags can be controlled via global settings: * The log level of individual buffers or tags can be controlled via global settings:
*
* ``` * ```
* # Echo any message to <bufferName> of <level> or higher * # Echo any message to <bufferName> of <level> or higher
* $ adb shell settings put global systemui/buffer/<bufferName> <level> * $ adb shell settings put global systemui/buffer/<bufferName> <level>

View File

@@ -30,7 +30,7 @@ import kotlin.math.max
* *
* @param maxSize The maximum size the buffer can grow to before it begins functioning as a ring. * @param maxSize The maximum size the buffer can grow to before it begins functioning as a ring.
* @param factory A function that creates a fresh instance of T. Used by the buffer while it's * @param factory A function that creates a fresh instance of T. Used by the buffer while it's
* growing to [maxSize]. * growing to [maxSize].
*/ */
class RingBuffer<T>(private val maxSize: Int, private val factory: () -> T) : Iterable<T> { class RingBuffer<T>(private val maxSize: Int, private val factory: () -> T) : Iterable<T> {

View File

@@ -87,7 +87,7 @@ internal object Evaluator {
* Helper for evaluating 3-valued logical AND/OR. * Helper for evaluating 3-valued logical AND/OR.
* *
* @param returnValueIfAnyMatches AND returns false if any value is false. OR returns true if * @param returnValueIfAnyMatches AND returns false if any value is false. OR returns true if
* any value is true. * any value is true.
*/ */
private fun threeValuedAndOrOr( private fun threeValuedAndOrOr(
conditions: Collection<Condition>, conditions: Collection<Condition>,

View File

@@ -132,6 +132,7 @@ private object InternalFaceAuthReasons {
/** /**
* UiEvents that are logged to identify why face auth is being triggered. * UiEvents that are logged to identify why face auth is being triggered.
*
* @param extraInfo is logged as the position. See [UiEventLogger#logWithInstanceIdAndPosition] * @param extraInfo is logged as the position. See [UiEventLogger#logWithInstanceIdAndPosition]
*/ */
enum class FaceAuthUiEvent enum class FaceAuthUiEvent

View File

@@ -49,8 +49,8 @@ constructor(
/** /**
* @property messagesToDefer messages that shouldn't show immediately when received, but may be * @property messagesToDefer messages that shouldn't show immediately when received, but may be
* shown later if the message is the most frequent acquiredInfo processed and meets [threshold] * shown later if the message is the most frequent acquiredInfo processed and meets [threshold]
* percentage of all passed acquired frames. * percentage of all passed acquired frames.
*/ */
open class BiometricMessageDeferral( open class BiometricMessageDeferral(
private val messagesToDefer: Set<Int>, private val messagesToDefer: Set<Int>,
@@ -127,8 +127,9 @@ open class BiometricMessageDeferral(
/** /**
* Get the most frequent deferred message that meets the [threshold] percentage of processed * Get the most frequent deferred message that meets the [threshold] percentage of processed
* frames. * frames.
*
* @return null if no acquiredInfo have been deferred OR deferred messages didn't meet the * @return null if no acquiredInfo have been deferred OR deferred messages didn't meet the
* [threshold] percentage. * [threshold] percentage.
*/ */
fun getDeferredMessage(): CharSequence? { fun getDeferredMessage(): CharSequence? {
mostFrequentAcquiredInfoToDefer?.let { mostFrequentAcquiredInfoToDefer?.let {

View File

@@ -492,7 +492,9 @@ class OrientationReasonListener(
displayManager, displayManager,
handler, handler,
BiometricDisplayListener.SensorType.SideFingerprint(sensorProps) BiometricDisplayListener.SensorType.SideFingerprint(sensorProps)
) { onOrientationChanged(reason) } ) {
onOrientationChanged(reason)
}
} }
/** /**

View File

@@ -347,6 +347,7 @@ constructor(
/** /**
* Overrides non-bouncer show logic in shouldPauseAuth to still show icon. * Overrides non-bouncer show logic in shouldPauseAuth to still show icon.
*
* @return whether the udfpsBouncer has been newly shown or hidden * @return whether the udfpsBouncer has been newly shown or hidden
*/ */
private fun showUdfpsBouncer(show: Boolean): Boolean { private fun showUdfpsBouncer(show: Boolean): Boolean {

View File

@@ -26,7 +26,6 @@ object ChannelExt {
/** /**
* Convenience wrapper around [SendChannel.trySend] that also logs on failure. This is the * Convenience wrapper around [SendChannel.trySend] that also logs on failure. This is the
* equivalent of calling: * equivalent of calling:
*
* ``` * ```
* sendChannel.trySend(element).onFailure { * sendChannel.trySend(element).onFailure {
* Log.e( * Log.e(

View File

@@ -86,6 +86,7 @@ internal constructor(wrapper: ControlsFavoritePersistenceWrapper) {
* *
* When the favorites for that application are returned, they will be removed from the auxiliary * When the favorites for that application are returned, they will be removed from the auxiliary
* file immediately, so they won't be retrieved again. * file immediately, so they won't be retrieved again.
*
* @param componentName the name of the service that provided the controls * @param componentName the name of the service that provided the controls
* @return a list of structures with favorites * @return a list of structures with favorites
*/ */

View File

@@ -38,7 +38,6 @@ import javax.inject.Inject
/** /**
* Manager to display a dialog to prompt user to enable controls related Settings: * Manager to display a dialog to prompt user to enable controls related Settings:
*
* * [Settings.Secure.LOCKSCREEN_SHOW_CONTROLS] * * [Settings.Secure.LOCKSCREEN_SHOW_CONTROLS]
* * [Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS] * * [Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS]
*/ */
@@ -46,20 +45,19 @@ interface ControlsSettingsDialogManager {
/** /**
* Shows the corresponding dialog. In order for a dialog to appear, the following must be true * Shows the corresponding dialog. In order for a dialog to appear, the following must be true
*
* * At least one of the Settings in [ControlsSettingsRepository] are `false`. * * At least one of the Settings in [ControlsSettingsRepository] are `false`.
* * The dialog has not been seen by the user too many times (as defined by * * The dialog has not been seen by the user too many times (as defined by
* [MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG]). * [MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG]).
* *
* When the dialogs are shown, the following outcomes are possible: * When the dialogs are shown, the following outcomes are possible:
* * User cancels the dialog by clicking outside or going back: we register that the dialog was * * User cancels the dialog by clicking outside or going back: we register that the dialog was
* seen but the settings don't change. * seen but the settings don't change.
* * User responds negatively to the dialog: we register that the user doesn't want to change * * User responds negatively to the dialog: we register that the user doesn't want to change
* the settings (dialog will not appear again) and the settings don't change. * the settings (dialog will not appear again) and the settings don't change.
* * User responds positively to the dialog: the settings are set to `true` and the dialog will * * User responds positively to the dialog: the settings are set to `true` and the dialog will
* not appear again. * not appear again.
* * SystemUI closes the dialogs (for example, the activity showing it is closed). In this case, * * SystemUI closes the dialogs (for example, the activity showing it is closed). In this case,
* we don't modify anything. * we don't modify anything.
* *
* Of those four scenarios, only the first three will cause [onAttemptCompleted] to be called. * Of those four scenarios, only the first three will cause [onAttemptCompleted] to be called.
* It will also be called if the dialogs are not shown. * It will also be called if the dialogs are not shown.

View File

@@ -128,7 +128,6 @@ constructor(
* *
* This is equivalent of creating a listener manually and adding an event handler for the given * This is equivalent of creating a listener manually and adding an event handler for the given
* command, like so: * command, like so:
*
* ``` * ```
* class Demoable { * class Demoable {
* private val demoHandler = object : DemoMode { * private val demoHandler = object : DemoMode {

View File

@@ -184,6 +184,7 @@ constructor(
/** /**
* Ends the dream content and dream overlay animations, if they're currently running. * Ends the dream content and dream overlay animations, if they're currently running.
*
* @see [AnimatorSet.end] * @see [AnimatorSet.end]
*/ */
fun endAnimations() { fun endAnimations() {

View File

@@ -134,7 +134,9 @@ constructor(
.flowOn(backgroundDispatcher) .flowOn(backgroundDispatcher)
.distinctUntilChanged() .distinctUntilChanged()
.onEach { settingsValue = it } .onEach { settingsValue = it }
) { callbackFlowValue, _ -> callbackFlowValue } ) { callbackFlowValue, _ ->
callbackFlowValue
}
override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState { override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
return if (controller.isZenAvailable) { return if (controller.isZenAvailable) {

View File

@@ -102,7 +102,8 @@ constructor(
// setup). // setup).
emit(Unit) emit(Unit)
} }
) { _, _ -> } ) { _, _ ->
}
.flatMapLatest { .flatMapLatest {
conflatedCallbackFlow { conflatedCallbackFlow {
// We want to instantiate a new SharedPreferences instance each time either the // We want to instantiate a new SharedPreferences instance each time either the

View File

@@ -53,6 +53,7 @@ interface KeyguardBouncerRepository {
val primaryBouncerScrimmed: StateFlow<Boolean> val primaryBouncerScrimmed: StateFlow<Boolean>
/** /**
* Set how much of the notification panel is showing on the screen. * Set how much of the notification panel is showing on the screen.
*
* ``` * ```
* 0f = panel fully hidden = bouncer fully showing * 0f = panel fully hidden = bouncer fully showing
* 1f = panel fully showing = bouncer fully hidden * 1f = panel fully showing = bouncer fully hidden
@@ -134,6 +135,7 @@ constructor(
override val primaryBouncerScrimmed = _primaryBouncerScrimmed.asStateFlow() override val primaryBouncerScrimmed = _primaryBouncerScrimmed.asStateFlow()
/** /**
* Set how much of the notification panel is showing on the screen. * Set how much of the notification panel is showing on the screen.
*
* ``` * ```
* 0f = panel fully hidden = bouncer fully showing * 0f = panel fully hidden = bouncer fully showing
* 1f = panel fully showing = bouncer fully hidden * 1f = panel fully showing = bouncer fully hidden

View File

@@ -50,6 +50,7 @@ constructor(
/** /**
* Sets the correct bouncer states to show the alternate bouncer if it can show. * Sets the correct bouncer states to show the alternate bouncer if it can show.
*
* @return whether alternateBouncer is visible * @return whether alternateBouncer is visible
*/ */
fun show(): Boolean { fun show(): Boolean {
@@ -74,6 +75,7 @@ constructor(
* Sets the correct bouncer states to hide the bouncer. Should only be called through * Sets the correct bouncer states to hide the bouncer. Should only be called through
* StatusBarKeyguardViewManager until ScrimController is refactored to use * StatusBarKeyguardViewManager until ScrimController is refactored to use
* alternateBouncerInteractor. * alternateBouncerInteractor.
*
* @return true if the alternate bouncer was newly hidden, else false. * @return true if the alternate bouncer was newly hidden, else false.
*/ */
fun hide(): Boolean { fun hide(): Boolean {

View File

@@ -71,8 +71,7 @@ constructor(
isPrimaryBouncerShowing, isPrimaryBouncerShowing,
lastStartedTransitionStep, lastStartedTransitionStep,
wakefulnessState, wakefulnessState,
isAodAvailable isAodAvailable) ->
) ->
if ( if (
!isAlternateBouncerShowing && !isAlternateBouncerShowing &&
!isPrimaryBouncerShowing && !isPrimaryBouncerShowing &&

View File

@@ -119,7 +119,7 @@ constructor(
* Notifies that a quick affordance has been "triggered" (clicked) by the user. * Notifies that a quick affordance has been "triggered" (clicked) by the user.
* *
* @param configKey The configuration key corresponding to the [KeyguardQuickAffordanceModel] of * @param configKey The configuration key corresponding to the [KeyguardQuickAffordanceModel] of
* the affordance that was clicked * the affordance that was clicked
* @param expandable An optional [Expandable] for the activity- or dialog-launch animation * @param expandable An optional [Expandable] for the activity- or dialog-launch animation
*/ */
fun onQuickAffordanceTriggered( fun onQuickAffordanceTriggered(
@@ -198,9 +198,9 @@ constructor(
* *
* @param slotId The ID of the slot. * @param slotId The ID of the slot.
* @param affordanceId The ID of the affordance to remove; if `null`, removes all affordances * @param affordanceId The ID of the affordance to remove; if `null`, removes all affordances
* from the slot. * from the slot.
* @return `true` if the affordance was successfully removed; `false` otherwise (for example, if * @return `true` if the affordance was successfully removed; `false` otherwise (for example, if
* the affordance was not on the slot to begin with). * the affordance was not on the slot to begin with).
*/ */
suspend fun unselect(slotId: String, affordanceId: String?): Boolean { suspend fun unselect(slotId: String, affordanceId: String?): Boolean {
check(isUsingRepository) check(isUsingRepository)

View File

@@ -34,7 +34,7 @@ object KeyguardLongPressViewBinder {
* @param viewModel The view-model that models the UI state. * @param viewModel The view-model that models the UI state.
* @param onSingleTap A callback to invoke when the system decides that there was a single tap. * @param onSingleTap A callback to invoke when the system decides that there was a single tap.
* @param falsingManager [FalsingManager] for making sure the long-press didn't just happen in * @param falsingManager [FalsingManager] for making sure the long-press didn't just happen in
* the user's pocket. * the user's pocket.
*/ */
@JvmStatic @JvmStatic
fun bind( fun bind(

View File

@@ -135,7 +135,7 @@ constructor(
* *
* @param initiallySelectedSlotId The ID of the initial slot to render as the selected one. * @param initiallySelectedSlotId The ID of the initial slot to render as the selected one.
* @param shouldHighlightSelectedAffordance Whether the selected quick affordance should be * @param shouldHighlightSelectedAffordance Whether the selected quick affordance should be
* highlighted (while all others are dimmed to make the selected one stand out). * highlighted (while all others are dimmed to make the selected one stand out).
*/ */
fun enablePreviewMode( fun enablePreviewMode(
initiallySelectedSlotId: String?, initiallySelectedSlotId: String?,

View File

@@ -47,13 +47,13 @@ import kotlinx.coroutines.launch
* fresh one. * fresh one.
* *
* @param coroutineContext An optional [CoroutineContext] to replace the dispatcher [block] is * @param coroutineContext An optional [CoroutineContext] to replace the dispatcher [block] is
* invoked on. * invoked on.
* @param block The block of code that should be run when the view becomes attached. It can end up * @param block The block of code that should be run when the view becomes attached. It can end up
* being invoked multiple times if the view is reattached after being detached. * being invoked multiple times if the view is reattached after being detached.
* @return A [DisposableHandle] to invoke when the caller of the function destroys its [View] and is * @return A [DisposableHandle] to invoke when the caller of the function destroys its [View] and is
* no longer interested in the [block] being run the next time its attached. Calling this is an * no longer interested in the [block] being run the next time its attached. Calling this is an
* optional optimization as the logic will be properly cleaned up and destroyed each time the view * optional optimization as the logic will be properly cleaned up and destroyed each time the view
* is detached. Using this is not *thread-safe* and should only be used on the main thread. * is detached. Using this is not *thread-safe* and should only be used on the main thread.
*/ */
@MainThread @MainThread
fun View.repeatWhenAttached( fun View.repeatWhenAttached(
@@ -125,7 +125,6 @@ private fun createLifecycleOwnerAndRun(
* The implementation requires the caller to call [onCreate] and [onDestroy] when the view is * The implementation requires the caller to call [onCreate] and [onDestroy] when the view is
* attached to or detached from a view hierarchy. After [onCreate] and before [onDestroy] is called, * attached to or detached from a view hierarchy. After [onCreate] and before [onDestroy] is called,
* the implementation monitors window state in the following way * the implementation monitors window state in the following way
*
* * If the window is not visible, we are in the [Lifecycle.State.CREATED] state * * If the window is not visible, we are in the [Lifecycle.State.CREATED] state
* * If the window is visible but not focused, we are in the [Lifecycle.State.STARTED] state * * If the window is visible but not focused, we are in the [Lifecycle.State.STARTED] state
* * If the window is visible and focused, we are in the [Lifecycle.State.RESUMED] state * * If the window is visible and focused, we are in the [Lifecycle.State.RESUMED] state

View File

@@ -16,7 +16,6 @@ private const val TAG = "KeyguardFaceAuthManagerLog"
* Helper class for logging for [com.android.keyguard.faceauth.KeyguardFaceAuthManager] * Helper class for logging for [com.android.keyguard.faceauth.KeyguardFaceAuthManager]
* *
* To enable logcat echoing for an entire buffer: * To enable logcat echoing for an entire buffer:
*
* ``` * ```
* adb shell settings put global systemui/buffer/KeyguardFaceAuthManagerLog <logLevel> * adb shell settings put global systemui/buffer/KeyguardFaceAuthManagerLog <logLevel>
* *

View File

@@ -33,7 +33,6 @@ private const val TAG = "ScreenDecorationsLog"
* Helper class for logging for [com.android.systemui.ScreenDecorations] * Helper class for logging for [com.android.systemui.ScreenDecorations]
* *
* To enable logcat echoing for an entire buffer: * To enable logcat echoing for an entire buffer:
*
* ``` * ```
* adb shell settings put global systemui/buffer/ScreenDecorationsLog <logLevel> * adb shell settings put global systemui/buffer/ScreenDecorationsLog <logLevel>
* *

View File

@@ -29,7 +29,6 @@ import kotlinx.coroutines.flow.Flow
* *
* Some parts of System UI maintain a lot of pieces of state at once. * Some parts of System UI maintain a lot of pieces of state at once.
* [com.android.systemui.plugins.log.LogBuffer] allows us to easily log change events: * [com.android.systemui.plugins.log.LogBuffer] allows us to easily log change events:
*
* - 10-10 10:10:10.456: state2 updated to newVal2 * - 10-10 10:10:10.456: state2 updated to newVal2
* - 10-10 10:11:00.000: stateN updated to StateN(val1=true, val2=1) * - 10-10 10:11:00.000: stateN updated to StateN(val1=true, val2=1)
* - 10-10 10:11:02.123: stateN updated to StateN(val1=true, val2=2) * - 10-10 10:11:02.123: stateN updated to StateN(val1=true, val2=2)
@@ -37,7 +36,6 @@ import kotlinx.coroutines.flow.Flow
* - 10-10 10:11:06.000: stateN updated to StateN(val1=false, val2=3) * - 10-10 10:11:06.000: stateN updated to StateN(val1=false, val2=3)
* *
* However, it can sometimes be more useful to view the state changes in table format: * However, it can sometimes be more useful to view the state changes in table format:
*
* - timestamp--------- | state1- | state2- | ... | stateN.val1 | stateN.val2 * - timestamp--------- | state1- | state2- | ... | stateN.val1 | stateN.val2
* - ------------------------------------------------------------------------- * - -------------------------------------------------------------------------
* - 10-10 10:10:10.123 | val1--- | val2--- | ... | false------ | 0----------- * - 10-10 10:10:10.123 | val1--- | val2--- | ... | false------ | 0-----------
@@ -56,23 +54,18 @@ import kotlinx.coroutines.flow.Flow
* individual fields. * individual fields.
* *
* How it works: * How it works:
*
* 1) Create an instance of this buffer via [TableLogBufferFactory]. * 1) Create an instance of this buffer via [TableLogBufferFactory].
*
* 2) For any states being logged, implement [Diffable]. Implementing [Diffable] allows the state to * 2) For any states being logged, implement [Diffable]. Implementing [Diffable] allows the state to
* only log the fields that have *changed* since the previous update, instead of always logging all * only log the fields that have *changed* since the previous update, instead of always logging
* fields. * all fields.
*
* 3) Each time a change in a state happens, call [logDiffs]. If your state is emitted using a * 3) Each time a change in a state happens, call [logDiffs]. If your state is emitted using a
* [Flow], you should use the [logDiffsForTable] extension function to automatically log diffs any * [Flow], you should use the [logDiffsForTable] extension function to automatically log diffs
* time your flow emits a new value. * any time your flow emits a new value.
* *
* When a dump occurs, there will be two dumps: * When a dump occurs, there will be two dumps:
*
* 1) The change events under the dumpable name "$name-changes". * 1) The change events under the dumpable name "$name-changes".
*
* 2) This class will coalesce all the diffs into a table format and log them under the dumpable * 2) This class will coalesce all the diffs into a table format and log them under the dumpable
* name "$name-table". * name "$name-table".
* *
* @param maxSize the maximum size of the buffer. Must be > 0. * @param maxSize the maximum size of the buffer. Must be > 0.
*/ */
@@ -99,11 +92,10 @@ class TableLogBuffer(
* The [newVal] object's method [Diffable.logDiffs] will be used to fetch the diffs. * The [newVal] object's method [Diffable.logDiffs] will be used to fetch the diffs.
* *
* @param columnPrefix a prefix that will be applied to every column name that gets logged. This * @param columnPrefix a prefix that will be applied to every column name that gets logged. This
* ensures that all the columns related to the same state object will be grouped together in the * ensures that all the columns related to the same state object will be grouped together in
* table. * the table.
*
* @throws IllegalArgumentException if [columnPrefix] or column name contain "|". "|" is used as * @throws IllegalArgumentException if [columnPrefix] or column name contain "|". "|" is used as
* the separator token for parsing, so it can't be present in any part of the column name. * the separator token for parsing, so it can't be present in any part of the column name.
*/ */
@Synchronized @Synchronized
fun <T : Diffable<T>> logDiffs(columnPrefix: String, prevVal: T, newVal: T) { fun <T : Diffable<T>> logDiffs(columnPrefix: String, prevVal: T, newVal: T) {
@@ -117,7 +109,7 @@ class TableLogBuffer(
* Logs change(s) to the buffer using [rowInitializer]. * Logs change(s) to the buffer using [rowInitializer].
* *
* @param rowInitializer a function that will be called immediately to store relevant data on * @param rowInitializer a function that will be called immediately to store relevant data on
* the row. * the row.
*/ */
@Synchronized @Synchronized
fun logChange(columnPrefix: String, rowInitializer: (TableRowLogger) -> Unit) { fun logChange(columnPrefix: String, rowInitializer: (TableRowLogger) -> Unit) {

View File

@@ -38,7 +38,6 @@ constructor(
* *
* @param name a unique table name * @param name a unique table name
* @param maxSize the buffer max size. See [adjustMaxSize] * @param maxSize the buffer max size. See [adjustMaxSize]
*
* @return a new [TableLogBuffer] registered with [DumpManager] * @return a new [TableLogBuffer] registered with [DumpManager]
*/ */
fun create( fun create(

View File

@@ -187,6 +187,7 @@ constructor(
/** /**
* Handle request to change the current position in the media track. * Handle request to change the current position in the media track.
*
* @param position Place to seek to in the track. * @param position Place to seek to in the track.
*/ */
@AnyThread @AnyThread

View File

@@ -52,6 +52,7 @@ data class SmartspaceMediaData(
* Indicates if all the data is valid. * Indicates if all the data is valid.
* *
* TODO(b/230333302): Make MediaControlPanel more flexible so that we can display fewer than * TODO(b/230333302): Make MediaControlPanel more flexible so that we can display fewer than
*
* ``` * ```
* [NUM_REQUIRED_RECOMMENDATIONS]. * [NUM_REQUIRED_RECOMMENDATIONS].
* ``` * ```

View File

@@ -329,9 +329,8 @@ constructor(
* Return the time since last active for the most-recent media. * Return the time since last active for the most-recent media.
* *
* @param sortedEntries userEntries sorted from the earliest to the most-recent. * @param sortedEntries userEntries sorted from the earliest to the most-recent.
*
* @return The duration in milliseconds from the most-recent media's last active timestamp to * @return The duration in milliseconds from the most-recent media's last active timestamp to
* the present. MAX_VALUE will be returned if there is no media. * the present. MAX_VALUE will be returned if there is no media.
*/ */
private fun timeSinceActiveForMostRecentMedia( private fun timeSinceActiveForMostRecentMedia(
sortedEntries: SortedMap<String, MediaData> sortedEntries: SortedMap<String, MediaData>

View File

@@ -525,8 +525,8 @@ class MediaDataManager(
* through the internal listener pipeline. * through the internal listener pipeline.
* *
* @param immediately indicates should apply the UI changes immediately, otherwise wait until * @param immediately indicates should apply the UI changes immediately, otherwise wait until
* the next refresh-round before UI becomes visible. Should only be true if the update is * the next refresh-round before UI becomes visible. Should only be true if the update is
* initiated by user's interaction. * initiated by user's interaction.
*/ */
private fun notifySmartspaceMediaDataRemoved(key: String, immediately: Boolean) { private fun notifySmartspaceMediaDataRemoved(key: String, immediately: Boolean) {
internalListeners.forEach { it.onSmartspaceMediaDataRemoved(key, immediately) } internalListeners.forEach { it.onSmartspaceMediaDataRemoved(key, immediately) }
@@ -535,6 +535,7 @@ class MediaDataManager(
/** /**
* Called whenever the player has been paused or stopped for a while, or swiped from QQS. This * Called whenever the player has been paused or stopped for a while, or swiped from QQS. This
* will make the player not active anymore, hiding it from QQS and Keyguard. * will make the player not active anymore, hiding it from QQS and Keyguard.
*
* @see MediaData.active * @see MediaData.active
*/ */
internal fun setTimedOut(key: String, timedOut: Boolean, forceUpdate: Boolean = false) { internal fun setTimedOut(key: String, timedOut: Boolean, forceUpdate: Boolean = false) {
@@ -1023,6 +1024,7 @@ class MediaDataManager(
* @param packageName Package name for the media app * @param packageName Package name for the media app
* @param controller MediaController for the current session * @param controller MediaController for the current session
* @return a Pair consisting of a list of media actions, and a list of ints representing which * @return a Pair consisting of a list of media actions, and a list of ints representing which
*
* ``` * ```
* of those actions should be shown in the compact player * of those actions should be shown in the compact player
* ``` * ```
@@ -1126,6 +1128,7 @@ class MediaDataManager(
* [PlaybackState.ACTION_SKIP_TO_NEXT] * [PlaybackState.ACTION_SKIP_TO_NEXT]
* @return * @return
* ``` * ```
*
* A [MediaAction] with correct values set, or null if the state doesn't support it * A [MediaAction] with correct values set, or null if the state doesn't support it
*/ */
private fun getStandardAction( private fun getStandardAction(
@@ -1226,6 +1229,7 @@ class MediaDataManager(
} }
/** /**
* Load a bitmap from a URI * Load a bitmap from a URI
*
* @param uri the uri to load * @param uri the uri to load
* @return bitmap, or null if couldn't be loaded * @return bitmap, or null if couldn't be loaded
*/ */
@@ -1519,15 +1523,13 @@ class MediaDataManager(
* notification key) or vice versa. * notification key) or vice versa.
* *
* @param immediately indicates should apply the UI changes immediately, otherwise wait * @param immediately indicates should apply the UI changes immediately, otherwise wait
* until the next refresh-round before UI becomes visible. True by default to take in place * until the next refresh-round before UI becomes visible. True by default to take in
* immediately. * place immediately.
*
* @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI * @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI
* displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace * displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace
* signal. * signal.
*
* @param isSsReactivated indicates resume media card is reactivated by Smartspace * @param isSsReactivated indicates resume media card is reactivated by Smartspace
* recommendation signal * recommendation signal
*/ */
fun onMediaDataLoaded( fun onMediaDataLoaded(
key: String, key: String,
@@ -1542,8 +1544,8 @@ class MediaDataManager(
* Called whenever there's new Smartspace media data loaded. * Called whenever there's new Smartspace media data loaded.
* *
* @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true, * @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true,
* it will be prioritized as the first card. Otherwise, it will show up as the last card as * it will be prioritized as the first card. Otherwise, it will show up as the last card
* default. * as default.
*/ */
fun onSmartspaceMediaDataLoaded( fun onSmartspaceMediaDataLoaded(
key: String, key: String,
@@ -1558,8 +1560,8 @@ class MediaDataManager(
* Called whenever a previously existing Smartspace media data was removed. * Called whenever a previously existing Smartspace media data was removed.
* *
* @param immediately indicates should apply the UI changes immediately, otherwise wait * @param immediately indicates should apply the UI changes immediately, otherwise wait
* until the next refresh-round before UI becomes visible. True by default to take in place * until the next refresh-round before UI becomes visible. True by default to take in
* immediately. * place immediately.
*/ */
fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean = true) {} fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean = true) {}
} }
@@ -1568,7 +1570,7 @@ class MediaDataManager(
* Converts the pass-in SmartspaceTarget to SmartspaceMediaData * Converts the pass-in SmartspaceTarget to SmartspaceMediaData
* *
* @return An empty SmartspaceMediaData with the valid target Id is returned if the * @return An empty SmartspaceMediaData with the valid target Id is returned if the
* SmartspaceTarget's data is invalid. * SmartspaceTarget's data is invalid.
*/ */
private fun toSmartspaceMediaData(target: SmartspaceTarget): SmartspaceMediaData { private fun toSmartspaceMediaData(target: SmartspaceTarget): SmartspaceMediaData {
var dismissIntent: Intent? = null var dismissIntent: Intent? = null

View File

@@ -408,9 +408,9 @@ constructor(
* [LocalMediaManager.DeviceCallback.onAboutToConnectDeviceAdded] for more information. * [LocalMediaManager.DeviceCallback.onAboutToConnectDeviceAdded] for more information.
* *
* @property fullMediaDevice a full-fledged [MediaDevice] object representing the device. If * @property fullMediaDevice a full-fledged [MediaDevice] object representing the device. If
* non-null, prefer using [fullMediaDevice] over [backupMediaDeviceData]. * non-null, prefer using [fullMediaDevice] over [backupMediaDeviceData].
* @property backupMediaDeviceData a backup [MediaDeviceData] object containing the minimum * @property backupMediaDeviceData a backup [MediaDeviceData] object containing the minimum
* information required to display the device. Only use if [fullMediaDevice] is null. * information required to display the device. Only use if [fullMediaDevice] is null.
*/ */
private data class AboutToConnectDevice( private data class AboutToConnectDevice(
val fullMediaDevice: MediaDevice? = null, val fullMediaDevice: MediaDevice? = null,

View File

@@ -60,6 +60,7 @@ constructor(
/** /**
* Callback representing that a media object is now expired: * Callback representing that a media object is now expired:
*
* @param key Media control unique identifier * @param key Media control unique identifier
* @param timedOut True when expired for {@code PAUSED_MEDIA_TIMEOUT} for active media, * @param timedOut True when expired for {@code PAUSED_MEDIA_TIMEOUT} for active media,
* ``` * ```
@@ -70,6 +71,7 @@ constructor(
/** /**
* Callback representing that a media object [PlaybackState] has changed. * Callback representing that a media object [PlaybackState] has changed.
*
* @param key Media control unique identifier * @param key Media control unique identifier
* @param state The new [PlaybackState] * @param state The new [PlaybackState]
*/ */
@@ -77,6 +79,7 @@ constructor(
/** /**
* Callback representing that the [MediaSession] for an active control has been destroyed * Callback representing that the [MediaSession] for an active control has been destroyed
*
* @param key Media control unique identifier * @param key Media control unique identifier
*/ */
lateinit var sessionCallback: (String) -> Unit lateinit var sessionCallback: (String) -> Unit

View File

@@ -297,6 +297,7 @@ constructor(
/** /**
* Add the component to the saved list of media browser services, checking for duplicates and * Add the component to the saved list of media browser services, checking for duplicates and
* removing older components that exceed the maximum limit * removing older components that exceed the maximum limit
*
* @param componentName * @param componentName
*/ */
private fun updateResumptionList(componentName: ComponentName) { private fun updateResumptionList(componentName: ComponentName) {

View File

@@ -52,10 +52,12 @@ class ResumeMediaBrowserLogger @Inject constructor(@MediaBrowserLog private val
* event. * event.
* *
* @param isBrowserConnected true if there's a currently connected * @param isBrowserConnected true if there's a currently connected
*
* ``` * ```
* [android.media.browse.MediaBrowser] and false otherwise. * [android.media.browse.MediaBrowser] and false otherwise.
* @param componentName * @param componentName
* ``` * ```
*
* the component name for the [ResumeMediaBrowser] that triggered this log. * the component name for the [ResumeMediaBrowser] that triggered this log.
*/ */
fun logSessionDestroyed(isBrowserConnected: Boolean, componentName: ComponentName) = fun logSessionDestroyed(isBrowserConnected: Boolean, componentName: ComponentName) =

View File

@@ -24,10 +24,12 @@ import android.graphics.drawable.Drawable
* and conflicts due to media notifications arriving at any time during an animation. It does this * and conflicts due to media notifications arriving at any time during an animation. It does this
* in two parts. * in two parts.
* - Exit animations fired as a result of user input are tracked. When these are running, any * - Exit animations fired as a result of user input are tracked. When these are running, any
*
* ``` * ```
* bind actions are delayed until the animation completes (and then fired in sequence). * bind actions are delayed until the animation completes (and then fired in sequence).
* ``` * ```
* - Continuous animations are tracked using their rebind id. Later calls using the same * - Continuous animations are tracked using their rebind id. Later calls using the same
*
* ``` * ```
* rebind id will be totally ignored to prevent the continuous animation from restarting. * rebind id will be totally ignored to prevent the continuous animation from restarting.
* ``` * ```

View File

@@ -201,7 +201,9 @@ internal constructor(
animatingColorTransitionFactory( animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorSecondary), loadDefaultColor(R.attr.textColorSecondary),
::textSecondaryFromScheme ::textSecondaryFromScheme
) { textSecondary -> mediaViewHolder.artistText.setTextColor(textSecondary) } ) { textSecondary ->
mediaViewHolder.artistText.setTextColor(textSecondary)
}
val textTertiary = val textTertiary =
animatingColorTransitionFactory( animatingColorTransitionFactory(

View File

@@ -159,6 +159,7 @@ class IlluminationDrawable : Drawable() {
/** /**
* Cross fade background. * Cross fade background.
*
* @see setTintList * @see setTintList
* @see backgroundColor * @see backgroundColor
*/ */

View File

@@ -853,10 +853,12 @@ constructor(
* @param startLocation the start location of our state or -1 if this is directly set * @param startLocation the start location of our state or -1 if this is directly set
* @param endLocation the ending location of our state. * @param endLocation the ending location of our state.
* @param progress the progress of the transition between startLocation and endlocation. If * @param progress the progress of the transition between startLocation and endlocation. If
*
* ``` * ```
* this is not a guided transformation, this will be 1.0f * this is not a guided transformation, this will be 1.0f
* @param immediately * @param immediately
* ``` * ```
*
* should this state be applied immediately, canceling all animations? * should this state be applied immediately, canceling all animations?
*/ */
fun setCurrentState( fun setCurrentState(
@@ -1100,17 +1102,17 @@ constructor(
* *
* @param eventId UI event id (e.g. 800 for SMARTSPACE_CARD_SEEN) * @param eventId UI event id (e.g. 800 for SMARTSPACE_CARD_SEEN)
* @param instanceId id to uniquely identify a card, e.g. each headphone generates a new * @param instanceId id to uniquely identify a card, e.g. each headphone generates a new
* instanceId * instanceId
* @param uid uid for the application that media comes from * @param uid uid for the application that media comes from
* @param surfaces list of display surfaces the media card is on (e.g. lockscreen, shade) when * @param surfaces list of display surfaces the media card is on (e.g. lockscreen, shade) when
* the event happened * the event happened
* @param interactedSubcardRank the rank for interacted media item for recommendation card, -1 * @param interactedSubcardRank the rank for interacted media item for recommendation card, -1
* for tapping on card but not on any media item, 0 for first media item, 1 for second, etc. * for tapping on card but not on any media item, 0 for first media item, 1 for second, etc.
* @param interactedSubcardCardinality how many media items were shown to the user when there is * @param interactedSubcardCardinality how many media items were shown to the user when there is
* user interaction * user interaction
* @param rank the rank for media card in the media carousel, starting from 0 * @param rank the rank for media card in the media carousel, starting from 0
* @param receivedLatencyMillis latency in milliseconds for card received events. E.g. latency * @param receivedLatencyMillis latency in milliseconds for card received events. E.g. latency
* between headphone connection to sysUI displays media recommendation card * between headphone connection to sysUI displays media recommendation card
* @param isSwipeToDismiss whether is to log swipe-to-dismiss event * @param isSwipeToDismiss whether is to log swipe-to-dismiss event
*/ */
fun logSmartspaceCardReported( fun logSmartspaceCardReported(
@@ -1371,6 +1373,7 @@ internal object MediaPlayerData {
/** /**
* Removes media player given the key. * Removes media player given the key.
*
* @param isDismissed determines whether the media player is removed from the carousel. * @param isDismissed determines whether the media player is removed from the carousel.
*/ */
fun removeMediaPlayer(key: String, isDismissed: Boolean = false) = fun removeMediaPlayer(key: String, isDismissed: Boolean = false) =

View File

@@ -417,8 +417,8 @@ constructor(
* Calculate the alpha of the view when given a cross-fade progress. * Calculate the alpha of the view when given a cross-fade progress.
* *
* @param crossFadeProgress The current cross fade progress. 0.5f means it's just switching * @param crossFadeProgress The current cross fade progress. 0.5f means it's just switching
* between the start and the end location and the content is fully faded, while 0.75f means that * between the start and the end location and the content is fully faded, while 0.75f means
* we're halfway faded in again in the target state. * that we're halfway faded in again in the target state.
*/ */
private fun calculateAlphaFromCrossFade(crossFadeProgress: Float): Float { private fun calculateAlphaFromCrossFade(crossFadeProgress: Float): Float {
if (crossFadeProgress <= 0.5f) { if (crossFadeProgress <= 0.5f) {
@@ -628,6 +628,7 @@ constructor(
* *
* @param forceNoAnimation optional parameter telling the system not to animate * @param forceNoAnimation optional parameter telling the system not to animate
* @param forceStateUpdate optional parameter telling the system to update transition state * @param forceStateUpdate optional parameter telling the system to update transition state
*
* ``` * ```
* even if location did not change * even if location did not change
* ``` * ```
@@ -943,7 +944,7 @@ constructor(
/** /**
* @return the current transformation progress if we're in a guided transformation and -1 * @return the current transformation progress if we're in a guided transformation and -1
* otherwise * otherwise
*/ */
private fun getTransformationProgress(): Float { private fun getTransformationProgress(): Float {
if (skipQqsOnExpansion) { if (skipQqsOnExpansion) {

View File

@@ -126,6 +126,7 @@ constructor(
* remeasurings later on. * remeasurings later on.
* *
* @param location the location this host name has. Used to identify the host during * @param location the location this host name has. Used to identify the host during
*
* ``` * ```
* transitions. * transitions.
* ``` * ```

View File

@@ -348,14 +348,17 @@ constructor(
* bottom of UMO reach the bottom of this group It will change to alpha 1.0 when the visible * bottom of UMO reach the bottom of this group It will change to alpha 1.0 when the visible
* bottom of UMO reach the top of the group below e.g.Album title, artist title and play-pause * bottom of UMO reach the top of the group below e.g.Album title, artist title and play-pause
* button will change alpha together. * button will change alpha together.
*
* ``` * ```
* And their alpha becomes 1.0 when the visible bottom of UMO reach the top of controls, * And their alpha becomes 1.0 when the visible bottom of UMO reach the top of controls,
* including progress bar, next button, previous button * including progress bar, next button, previous button
* ``` * ```
*
* widgetGroupIds: a group of widgets have same state during UMO is squished, * widgetGroupIds: a group of widgets have same state during UMO is squished,
* ``` * ```
* e.g. Album title, artist title and play-pause button * e.g. Album title, artist title and play-pause button
* ``` * ```
*
* groupEndPosition: the height of UMO, when the height reaches this value, * groupEndPosition: the height of UMO, when the height reaches this value,
* ``` * ```
* widgets in this group should have 1.0 as alpha * widgets in this group should have 1.0 as alpha
@@ -363,6 +366,7 @@ constructor(
* visible when the height of UMO reaches the top of controls group * visible when the height of UMO reaches the top of controls group
* (progress bar, previous button and next button) * (progress bar, previous button and next button)
* ``` * ```
*
* squishedViewState: hold the widgetState of each widget, which will be modified * squishedViewState: hold the widgetState of each widget, which will be modified
* squishFraction: the squishFraction of UMO * squishFraction: the squishFraction of UMO
*/ */
@@ -665,7 +669,7 @@ constructor(
* *
* @param location Target * @param location Target
* @param locationWhenHidden Location that will be used when the target is not * @param locationWhenHidden Location that will be used when the target is not
* [MediaHost.visible] * [MediaHost.visible]
* @return State require for executing a transition, and also the respective [MediaHost]. * @return State require for executing a transition, and also the respective [MediaHost].
*/ */
private fun obtainViewStateForLocation(@MediaLocation location: Int): TransitionViewState? { private fun obtainViewStateForLocation(@MediaLocation location: Int): TransitionViewState? {

View File

@@ -43,7 +43,7 @@ class MediaTttUtils {
* *
* @param appPackageName the package name of the app playing the media. * @param appPackageName the package name of the app playing the media.
* @param onPackageNotFoundException a function run if a * @param onPackageNotFoundException a function run if a
* [PackageManager.NameNotFoundException] occurs. * [PackageManager.NameNotFoundException] occurs.
* @param isReceiver indicates whether the icon is displayed in a receiver view. * @param isReceiver indicates whether the icon is displayed in a receiver view.
*/ */
fun getIconInfoFromPackageName( fun getIconInfoFromPackageName(

View File

@@ -70,6 +70,8 @@ constructor(
RECENT_IGNORE_UNAVAILABLE, RECENT_IGNORE_UNAVAILABLE,
userTracker.userId, userTracker.userId,
backgroundExecutor backgroundExecutor
) { tasks -> continuation.resume(tasks) } ) { tasks ->
continuation.resume(tasks)
}
} }
} }

View File

@@ -33,8 +33,8 @@ import javax.inject.Inject
* launched, creating a new shortcut for [CreateNoteTaskShortcutActivity], and will finish. * launched, creating a new shortcut for [CreateNoteTaskShortcutActivity], and will finish.
* *
* @see <a * @see <a
* href="https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts#custom-pinned">Creating * href="https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts#custom-pinned">Creating
* a custom shortcut activity</a> * a custom shortcut activity</a>
*/ */
internal class CreateNoteTaskShortcutActivity @Inject constructor() : ComponentActivity() { internal class CreateNoteTaskShortcutActivity @Inject constructor() : ComponentActivity() {

View File

@@ -26,8 +26,7 @@ import dagger.multibindings.StringKey
@Module @Module
interface QRCodeScannerModule { interface QRCodeScannerModule {
/** /** */
*/
@Binds @Binds
@IntoMap @IntoMap
@StringKey(QRCodeScannerTile.TILE_SPEC) @StringKey(QRCodeScannerTile.TILE_SPEC)

View File

@@ -71,8 +71,8 @@ interface FooterActionsInteractor {
/** /**
* Show the device monitoring dialog, expanded from [expandable] if it's not null. * Show the device monitoring dialog, expanded from [expandable] if it's not null.
* *
* Important: [quickSettingsContext] *must* be the [Context] associated to the [Quick Settings * Important: [quickSettingsContext] *must* be the [Context] associated to the
* fragment][com.android.systemui.qs.QSFragment]. * [Quick Settings fragment][com.android.systemui.qs.QSFragment].
*/ */
fun showDeviceMonitoringDialog(quickSettingsContext: Context, expandable: Expandable?) fun showDeviceMonitoringDialog(quickSettingsContext: Context, expandable: Expandable?)

View File

@@ -196,9 +196,9 @@ class FooterActionsViewModel(
* Observe the device monitoring dialog requests and show the dialog accordingly. This function * Observe the device monitoring dialog requests and show the dialog accordingly. This function
* will suspend indefinitely and will need to be cancelled to stop observing. * will suspend indefinitely and will need to be cancelled to stop observing.
* *
* Important: [quickSettingsContext] must be the [Context] associated to the [Quick Settings * Important: [quickSettingsContext] must be the [Context] associated to the
* fragment][com.android.systemui.qs.QSFragment], and the call to this function must be * [Quick Settings fragment][com.android.systemui.qs.QSFragment], and the call to this function
* cancelled when that fragment is destroyed. * must be cancelled when that fragment is destroyed.
*/ */
suspend fun observeDeviceMonitoringDialogRequests(quickSettingsContext: Context) { suspend fun observeDeviceMonitoringDialogRequests(quickSettingsContext: Context) {
footerActionsInteractor.deviceMonitoringDialogRequests.collect { footerActionsInteractor.deviceMonitoringDialogRequests.collect {

View File

@@ -124,8 +124,9 @@ class ScreenRecordPermissionDialog(
/** /**
* Starts screen capture after some countdown * Starts screen capture after some countdown
*
* @param captureTarget target to capture (could be e.g. a task) or null to record the whole * @param captureTarget target to capture (could be e.g. a task) or null to record the whole
* screen * screen
*/ */
private fun requestScreenCapture(captureTarget: MediaProjectionCaptureTarget?) { private fun requestScreenCapture(captureTarget: MediaProjectionCaptureTarget?) {
val userContext = userContextProvider.userContext val userContext = userContextProvider.userContext

View File

@@ -70,7 +70,7 @@ object ActionIntentCreator {
/** /**
* @return an ACTION_EDIT intent for the given URI, directed to config_screenshotEditor if * @return an ACTION_EDIT intent for the given URI, directed to config_screenshotEditor if
* available. * available.
*/ */
fun createEditIntent(uri: Uri, context: Context): Intent { fun createEditIntent(uri: Uri, context: Context): Intent {
val editIntent = Intent(Intent.ACTION_EDIT) val editIntent = Intent(Intent.ACTION_EDIT)

View File

@@ -44,7 +44,7 @@ constructor(
/** /**
* @return a populated WorkProfileFirstRunData object if a work profile first run message should * @return a populated WorkProfileFirstRunData object if a work profile first run message should
* be shown * be shown
*/ */
fun onScreenshotTaken(userHandle: UserHandle?): WorkProfileFirstRunData? { fun onScreenshotTaken(userHandle: UserHandle?): WorkProfileFirstRunData? {
if (userHandle == null) return null if (userHandle == null) return null

View File

@@ -107,7 +107,7 @@ class ShadeExpansionStateManager @Inject constructor() : ShadeStateEvents {
* *
* @param fraction the fraction from the expansion in [0, 1] * @param fraction the fraction from the expansion in [0, 1]
* @param expanded whether the panel is currently expanded; this is independent from the * @param expanded whether the panel is currently expanded; this is independent from the
* fraction as the panel also might be expanded if the fraction is 0. * fraction as the panel also might be expanded if the fraction is 0.
* @param tracking whether we're currently tracking the user's gesture. * @param tracking whether we're currently tracking the user's gesture.
*/ */
fun onPanelExpansionChanged( fun onPanelExpansionChanged(

View File

@@ -70,9 +70,9 @@ import javax.inject.Named
* *
* [header] is a [MotionLayout] that has two transitions: * [header] is a [MotionLayout] that has two transitions:
* * [HEADER_TRANSITION_ID]: [QQS_HEADER_CONSTRAINT] <-> [QS_HEADER_CONSTRAINT] for portrait * * [HEADER_TRANSITION_ID]: [QQS_HEADER_CONSTRAINT] <-> [QS_HEADER_CONSTRAINT] for portrait
* handheld device configuration. * handheld device configuration.
* * [LARGE_SCREEN_HEADER_TRANSITION_ID]: [LARGE_SCREEN_HEADER_CONSTRAINT] for all other * * [LARGE_SCREEN_HEADER_TRANSITION_ID]: [LARGE_SCREEN_HEADER_CONSTRAINT] for all other
* configurations * configurations
*/ */
@CentralSurfacesScope @CentralSurfacesScope
class ShadeHeaderController class ShadeHeaderController

View File

@@ -148,7 +148,8 @@ constructor(
qsDragFraction: $qsTransitionFraction qsDragFraction: $qsTransitionFraction
qsSquishFraction: $qsSquishTransitionFraction qsSquishFraction: $qsSquishTransitionFraction
isTransitioningToFullShade: $isTransitioningToFullShade isTransitioningToFullShade: $isTransitioningToFullShade
""".trimIndent() """
.trimIndent()
) )
} }

View File

@@ -74,7 +74,7 @@ constructor(
/** /**
* @return a context with the MCC/MNC [Configuration] values corresponding to this * @return a context with the MCC/MNC [Configuration] values corresponding to this
* subscriptionId * subscriptionId
*/ */
fun getMobileContextForSub(subId: Int, context: Context): Context { fun getMobileContextForSub(subId: Int, context: Context): Context {
if (demoModeController.isInDemoMode) { if (demoModeController.isInDemoMode) {

View File

@@ -39,6 +39,7 @@ import javax.inject.Inject
* - Simple prioritization: Privacy > Battery > connectivity (encoded in [StatusEvent]) * - Simple prioritization: Privacy > Battery > connectivity (encoded in [StatusEvent])
* - Only schedules a single event, and throws away lowest priority events * - Only schedules a single event, and throws away lowest priority events
* ``` * ```
*
* There are 4 basic stages of animation at play here: * There are 4 basic stages of animation at play here:
* ``` * ```
* 1. System chrome animation OUT * 1. System chrome animation OUT
@@ -46,6 +47,7 @@ import javax.inject.Inject
* 3. Chip animation OUT; potentially into a dot * 3. Chip animation OUT; potentially into a dot
* 4. System chrome animation IN * 4. System chrome animation IN
* ``` * ```
*
* Thus we can keep all animations synchronized with two separate ValueAnimators, one for system * Thus we can keep all animations synchronized with two separate ValueAnimators, one for system
* chrome and the other for the chip. These can animate from 0,1 and listeners can parameterize * chrome and the other for the chip. These can animate from 0,1 and listeners can parameterize
* their respective views based on the progress of the animator. Interpolation differences TBD * their respective views based on the progress of the animator. Interpolation differences TBD
@@ -168,7 +170,7 @@ constructor(
* 3. Update the scheduler state so that clients know where we are * 3. Update the scheduler state so that clients know where we are
* 4. Maybe: provide scaffolding such as: dot location, margins, etc * 4. Maybe: provide scaffolding such as: dot location, margins, etc
* 5. Maybe: define a maximum animation length and enforce it. Probably only doable if we * 5. Maybe: define a maximum animation length and enforce it. Probably only doable if we
* collect all of the animators and run them together. * collect all of the animators and run them together.
*/ */
private fun runChipAnimation() { private fun runChipAnimation() {
statusBarWindowController.setForceStatusBarVisible(true) statusBarWindowController.setForceStatusBarVisible(true)

View File

@@ -315,6 +315,7 @@ interface Roundable {
/** /**
* State object for a `Roundable` class. * State object for a `Roundable` class.
*
* @param targetView Will handle the [AnimatableProperty] * @param targetView Will handle the [AnimatableProperty]
* @param roundable Target of the radius animation * @param roundable Target of the radius animation
* @param maxRadius Max corner radius in pixels * @param maxRadius Max corner radius in pixels
@@ -436,7 +437,6 @@ interface SourceType {
* This is the most convenient way to define a new [SourceType]. * This is the most convenient way to define a new [SourceType].
* *
* For example: * For example:
*
* ```kotlin * ```kotlin
* private val SECTION = SourceType.from("Section") * private val SECTION = SourceType.from("Section")
* ``` * ```

View File

@@ -25,9 +25,10 @@ constructor(
/** /**
* This method looks for views that can be rounded (and implement [Roundable]) during a * This method looks for views that can be rounded (and implement [Roundable]) during a
* notification swipe. * notification swipe.
*
* @return The [Roundable] targets above/below the [viewSwiped] (if available). The * @return The [Roundable] targets above/below the [viewSwiped] (if available). The
* [RoundableTargets.before] and [RoundableTargets.after] parameters can be `null` if there is * [RoundableTargets.before] and [RoundableTargets.after] parameters can be `null` if there is
* no above/below notification or the notification is not part of the same section. * no above/below notification or the notification is not part of the same section.
*/ */
fun findRoundableTargets( fun findRoundableTargets(
viewSwiped: ExpandableNotificationRow, viewSwiped: ExpandableNotificationRow,

View File

@@ -45,7 +45,7 @@ import kotlinx.coroutines.flow.asStateFlow
* 1. Define a new `private val` wrapping the key using [BooleanCarrierConfig] * 1. Define a new `private val` wrapping the key using [BooleanCarrierConfig]
* 2. Define a public `val` exposing the wrapped flow using [BooleanCarrierConfig.config] * 2. Define a public `val` exposing the wrapped flow using [BooleanCarrierConfig.config]
* 3. Add the new [BooleanCarrierConfig] to the list of tracked configs, so they are properly * 3. Add the new [BooleanCarrierConfig] to the list of tracked configs, so they are properly
* updated when a new carrier config comes down * updated when a new carrier config comes down
*/ */
class SystemUiCarrierConfig class SystemUiCarrierConfig
internal constructor( internal constructor(

View File

@@ -353,8 +353,8 @@ constructor(
* True if the checked subId is in the list of current subs or the active mobile data subId * True if the checked subId is in the list of current subs or the active mobile data subId
* *
* @param checkedSubs the list to validate [subId] against. To invalidate the cache, pass in the * @param checkedSubs the list to validate [subId] against. To invalidate the cache, pass in the
* new subscription list. Otherwise use [subscriptions.value] to validate a subId against the * new subscription list. Otherwise use [subscriptions.value] to validate a subId against the
* current known subscriptions * current known subscriptions
*/ */
private fun checkSub(subId: Int, checkedSubs: List<SubscriptionModel>): Boolean { private fun checkSub(subId: Int, checkedSubs: List<SubscriptionModel>): Boolean {
if (activeMobileDataSubscriptionId.value == subId) return true if (activeMobileDataSubscriptionId.value == subId) return true

View File

@@ -92,7 +92,8 @@ interface MobileIconInteractor {
* 1. The default network name, if one is configured * 1. The default network name, if one is configured
* 2. A derived name based off of the intent [ACTION_SERVICE_PROVIDERS_UPDATED] * 2. A derived name based off of the intent [ACTION_SERVICE_PROVIDERS_UPDATED]
* 3. Or, in the case where the repository sends us the default network name, we check for an * 3. Or, in the case where the repository sends us the default network name, we check for an
* override in [connectionInfo.operatorAlphaShort], a value that is derived from [ServiceState] * override in [connectionInfo.operatorAlphaShort], a value that is derived from
* [ServiceState]
*/ */
val networkName: StateFlow<NetworkNameModel> val networkName: StateFlow<NetworkNameModel>

View File

@@ -25,7 +25,7 @@ import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
* allows the mobile icon to change some view parameters at different locations * allows the mobile icon to change some view parameters at different locations
* *
* @param commonImpl for convenience, this class wraps a base interface that can provides all of the * @param commonImpl for convenience, this class wraps a base interface that can provides all of the
* common implementations between locations. See [MobileIconViewModel] * common implementations between locations. See [MobileIconViewModel]
*/ */
abstract class LocationBasedMobileViewModel( abstract class LocationBasedMobileViewModel(
val commonImpl: MobileIconViewModelCommon, val commonImpl: MobileIconViewModelCommon,

View File

@@ -41,7 +41,6 @@ import kotlinx.coroutines.flow.stateIn
* or the [WifiRepositoryImpl]'s prod implementation, based on the current demo mode value. In this * or the [WifiRepositoryImpl]'s prod implementation, based on the current demo mode value. In this
* way, downstream clients can all consist of real implementations and not care about which * way, downstream clients can all consist of real implementations and not care about which
* repository is responsible for the data. Graphically: * repository is responsible for the data. Graphically:
*
* ``` * ```
* RealRepository * RealRepository
* │ * │

View File

@@ -146,7 +146,7 @@ constructor(
* *
* @param guestUserId id of the guest user to remove * @param guestUserId id of the guest user to remove
* @param targetUserId id of the user to switch to after guest is removed. If * @param targetUserId id of the user to switch to after guest is removed. If
* `UserHandle.USER_NULL`, then switch immediately to the newly created guest user. * `UserHandle.USER_NULL`, then switch immediately to the newly created guest user.
*/ */
fun removeGuestUser(guestUserId: Int, targetUserId: Int) { fun removeGuestUser(guestUserId: Int, targetUserId: Int) {
userInteractor.removeGuestUser( userInteractor.removeGuestUser(
@@ -160,9 +160,9 @@ constructor(
* *
* @param guestUserId user id of the guest user to exit * @param guestUserId user id of the guest user to exit
* @param targetUserId user id of the guest user to exit, set to UserHandle#USER_NULL when * @param targetUserId user id of the guest user to exit, set to UserHandle#USER_NULL when
* target user id is not known * target user id is not known
* @param forceRemoveGuestOnExit true: remove guest before switching user, false: remove guest * @param forceRemoveGuestOnExit true: remove guest before switching user, false: remove guest
* only if its ephemeral, else keep guest * only if its ephemeral, else keep guest
*/ */
fun exitGuestUser(guestUserId: Int, targetUserId: Int, forceRemoveGuestOnExit: Boolean) { fun exitGuestUser(guestUserId: Int, targetUserId: Int, forceRemoveGuestOnExit: Boolean) {
userInteractor.exitGuestUser(guestUserId, targetUserId, forceRemoveGuestOnExit) userInteractor.exitGuestUser(guestUserId, targetUserId, forceRemoveGuestOnExit)

View File

@@ -27,7 +27,7 @@ import com.android.systemui.util.ViewController
* pass through to the window below. * pass through to the window below.
* *
* @param touchableRegionSetter a function that, given the view and an out rect, fills the rect with * @param touchableRegionSetter a function that, given the view and an out rect, fills the rect with
* the touchable region of this view. * the touchable region of this view.
*/ */
class TouchableRegionViewController( class TouchableRegionViewController(
view: View, view: View,

View File

@@ -35,7 +35,7 @@ open class ChipbarAnimator @Inject constructor() {
* Animates [innerView] and its children into view. * Animates [innerView] and its children into view.
* *
* @return true if the animation was successfully started and false if the animation can't be * @return true if the animation was successfully started and false if the animation can't be
* run for any reason. * run for any reason.
* *
* See [ViewHierarchyAnimator.animateAddition]. * See [ViewHierarchyAnimator.animateAddition].
*/ */
@@ -55,7 +55,7 @@ open class ChipbarAnimator @Inject constructor() {
* Animates [innerView] and its children out of view. * Animates [innerView] and its children out of view.
* *
* @return true if the animation was successfully started and false if the animation can't be * @return true if the animation was successfully started and false if the animation can't be
* run for any reason. * run for any reason.
* *
* See [ViewHierarchyAnimator.animateRemoval]. * See [ViewHierarchyAnimator.animateRemoval].
*/ */

View File

@@ -28,10 +28,10 @@ import com.android.systemui.temporarydisplay.ViewPriority
* A container for all the state needed to display a chipbar via [ChipbarCoordinator]. * A container for all the state needed to display a chipbar via [ChipbarCoordinator].
* *
* @property startIcon the icon to display at the start of the chipbar (on the left in LTR locales; * @property startIcon the icon to display at the start of the chipbar (on the left in LTR locales;
* on the right in RTL locales). * on the right in RTL locales).
* @property text the text to display. * @property text the text to display.
* @property endItem an optional end item to display at the end of the chipbar (on the right in LTR * @property endItem an optional end item to display at the end of the chipbar (on the right in LTR
* locales; on the left in RTL locales). * locales; on the left in RTL locales).
* @property vibrationEffect an optional vibration effect when the chipbar is displayed * @property vibrationEffect an optional vibration effect when the chipbar is displayed
* @property allowSwipeToDismiss true if users are allowed to swipe up to dismiss this chipbar. * @property allowSwipeToDismiss true if users are allowed to swipe up to dismiss this chipbar.
*/ */

View File

@@ -297,7 +297,7 @@ constructor(
* to create a new one. * to create a new one.
* *
* @return The multi-user user ID of the newly created guest user, or [UserHandle.USER_NULL] if * @return The multi-user user ID of the newly created guest user, or [UserHandle.USER_NULL] if
* the guest couldn't be created. * the guest couldn't be created.
*/ */
@UserIdInt @UserIdInt
private suspend fun createInBackground(): Int { private suspend fun createInBackground(): Int {

View File

@@ -354,7 +354,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.X_ALIGNED, deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_0 } { rotation = Surface.ROTATION_0 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_90() = fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_90() =
@@ -362,7 +364,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.X_ALIGNED, deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_90 } { rotation = Surface.ROTATION_90 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_180() = fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_180() =
@@ -370,7 +374,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.X_ALIGNED, deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_180 } { rotation = Surface.ROTATION_180 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarCollapsedDownForXAlignedSensor_180() = fun showsSfpsIndicatorWithTaskbarCollapsedDownForXAlignedSensor_180() =
@@ -379,7 +385,9 @@ class SideFpsControllerTest : SysuiTestCase() {
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_180 }, { rotation = Surface.ROTATION_180 },
windowInsets = insetsForSmallNavbar() windowInsets = insetsForSmallNavbar()
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun hidesSfpsIndicatorWhenOccludingTaskbarForXAlignedSensor_180() = fun hidesSfpsIndicatorWhenOccludingTaskbarForXAlignedSensor_180() =
@@ -388,7 +396,9 @@ class SideFpsControllerTest : SysuiTestCase() {
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_180 }, { rotation = Surface.ROTATION_180 },
windowInsets = insetsForLargeNavbar() windowInsets = insetsForLargeNavbar()
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_270() = fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_270() =
@@ -396,7 +406,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.X_ALIGNED, deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_270 } { rotation = Surface.ROTATION_270 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_0() = fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_0() =
@@ -404,7 +416,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.X_ALIGNED, deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_0 } { rotation = Surface.ROTATION_0 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_90() = fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_90() =
@@ -412,7 +426,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.X_ALIGNED, deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_90 } { rotation = Surface.ROTATION_90 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarCollapsedDownForXAlignedSensor_InReverseDefaultRotation_90() = fun showsSfpsIndicatorWithTaskbarCollapsedDownForXAlignedSensor_InReverseDefaultRotation_90() =
@@ -421,7 +437,9 @@ class SideFpsControllerTest : SysuiTestCase() {
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_90 }, { rotation = Surface.ROTATION_90 },
windowInsets = insetsForSmallNavbar() windowInsets = insetsForSmallNavbar()
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun hidesSfpsIndicatorWhenOccludingTaskbarForXAlignedSensor_InReverseDefaultRotation_90() = fun hidesSfpsIndicatorWhenOccludingTaskbarForXAlignedSensor_InReverseDefaultRotation_90() =
@@ -430,7 +448,9 @@ class SideFpsControllerTest : SysuiTestCase() {
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_90 }, { rotation = Surface.ROTATION_90 },
windowInsets = insetsForLargeNavbar() windowInsets = insetsForLargeNavbar()
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_180() = fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_180() =
@@ -438,7 +458,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.X_ALIGNED, deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_180 } { rotation = Surface.ROTATION_180 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_270() = fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_270() =
@@ -446,7 +468,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.X_ALIGNED, deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_270 } { rotation = Surface.ROTATION_270 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_0() = fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_0() =
@@ -454,7 +478,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.Y_ALIGNED, deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_0 } { rotation = Surface.ROTATION_0 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_90() = fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_90() =
@@ -462,7 +488,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.Y_ALIGNED, deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_90 } { rotation = Surface.ROTATION_90 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_180() = fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_180() =
@@ -480,7 +508,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.Y_ALIGNED, deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_270 } { rotation = Surface.ROTATION_270 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarCollapsedDownForYAlignedSensor_270() = fun showsSfpsIndicatorWithTaskbarCollapsedDownForYAlignedSensor_270() =
@@ -489,7 +519,9 @@ class SideFpsControllerTest : SysuiTestCase() {
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_270 }, { rotation = Surface.ROTATION_270 },
windowInsets = insetsForSmallNavbar() windowInsets = insetsForSmallNavbar()
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun hidesSfpsIndicatorWhenOccludingTaskbarForYAlignedSensor_270() = fun hidesSfpsIndicatorWhenOccludingTaskbarForYAlignedSensor_270() =
@@ -498,7 +530,9 @@ class SideFpsControllerTest : SysuiTestCase() {
isReverseDefaultRotation = false, isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_270 }, { rotation = Surface.ROTATION_270 },
windowInsets = insetsForLargeNavbar() windowInsets = insetsForLargeNavbar()
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_0() = fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_0() =
@@ -506,7 +540,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.Y_ALIGNED, deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_0 } { rotation = Surface.ROTATION_0 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_90() = fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_90() =
@@ -524,7 +560,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.Y_ALIGNED, deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_180 } { rotation = Surface.ROTATION_180 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarCollapsedDownForYAlignedSensor_InReverseDefaultRotation_180() = fun showsSfpsIndicatorWithTaskbarCollapsedDownForYAlignedSensor_InReverseDefaultRotation_180() =
@@ -533,7 +571,9 @@ class SideFpsControllerTest : SysuiTestCase() {
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_180 }, { rotation = Surface.ROTATION_180 },
windowInsets = insetsForSmallNavbar() windowInsets = insetsForSmallNavbar()
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun hidesSfpsIndicatorWhenOccludingTaskbarForYAlignedSensor_InReverseDefaultRotation_180() = fun hidesSfpsIndicatorWhenOccludingTaskbarForYAlignedSensor_InReverseDefaultRotation_180() =
@@ -542,7 +582,9 @@ class SideFpsControllerTest : SysuiTestCase() {
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_180 }, { rotation = Surface.ROTATION_180 },
windowInsets = insetsForLargeNavbar() windowInsets = insetsForLargeNavbar()
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false)
}
@Test @Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_270() = fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_270() =
@@ -550,7 +592,9 @@ class SideFpsControllerTest : SysuiTestCase() {
deviceConfig = DeviceConfig.Y_ALIGNED, deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = true, isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_270 } { rotation = Surface.ROTATION_270 }
) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) } ) {
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
@Test @Test
fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_0() = fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_0() =

View File

@@ -104,7 +104,9 @@ class ControlsSettingsDialogManagerImplTest : SysuiTestCase() {
controlsSettingsRepository, controlsSettingsRepository,
userTracker, userTracker,
activityStarter activityStarter
) { context, _ -> TestableAlertDialog(context).also { dialog = it } } ) { context, _ ->
TestableAlertDialog(context).also { dialog = it }
}
} }
@After @After

View File

@@ -37,7 +37,9 @@ class OverflowMenuAdapterTest : SysuiTestCase() {
context, context,
layoutId = 0, layoutId = 0,
labels.zip(ids).map { OverflowMenuAdapter.MenuItem(it.first, it.second) } labels.zip(ids).map { OverflowMenuAdapter.MenuItem(it.first, it.second) }
) { true } ) {
true
}
ids.forEachIndexed { index, id -> assertThat(adapter.getItemId(index)).isEqualTo(id) } ids.forEachIndexed { index, id -> assertThat(adapter.getItemId(index)).isEqualTo(id) }
} }
@@ -51,7 +53,9 @@ class OverflowMenuAdapterTest : SysuiTestCase() {
context, context,
layoutId = 0, layoutId = 0,
labels.zip(ids).map { OverflowMenuAdapter.MenuItem(it.first, it.second) } labels.zip(ids).map { OverflowMenuAdapter.MenuItem(it.first, it.second) }
) { position -> position == 0 } ) { position ->
position == 0
}
assertThat(adapter.isEnabled(0)).isTrue() assertThat(adapter.isEnabled(0)).isTrue()
assertThat(adapter.isEnabled(1)).isFalse() assertThat(adapter.isEnabled(1)).isFalse()

View File

@@ -62,7 +62,9 @@ class LightRevealScrimRepositoryTest : SysuiTestCase() {
fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockModel.WAKE_AND_UNLOCK) fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockModel.WAKE_AND_UNLOCK)
runCurrent() runCurrent()
values.assertEffectsMatchPredicates({ it == DEFAULT_REVEAL_EFFECT },) values.assertEffectsMatchPredicates(
{ it == DEFAULT_REVEAL_EFFECT },
)
// We got a source but still have no sensor locations, so should be sticking with // We got a source but still have no sensor locations, so should be sticking with
// the default effect. // the default effect.
@@ -71,14 +73,18 @@ class LightRevealScrimRepositoryTest : SysuiTestCase() {
) )
runCurrent() runCurrent()
values.assertEffectsMatchPredicates({ it == DEFAULT_REVEAL_EFFECT },) values.assertEffectsMatchPredicates(
{ it == DEFAULT_REVEAL_EFFECT },
)
// We got a location for the face sensor, but we unlocked with fingerprint. // We got a location for the face sensor, but we unlocked with fingerprint.
val faceLocation = Point(250, 0) val faceLocation = Point(250, 0)
fakeKeyguardRepository.setFaceSensorLocation(faceLocation) fakeKeyguardRepository.setFaceSensorLocation(faceLocation)
runCurrent() runCurrent()
values.assertEffectsMatchPredicates({ it == DEFAULT_REVEAL_EFFECT },) values.assertEffectsMatchPredicates(
{ it == DEFAULT_REVEAL_EFFECT },
)
// Now we have fingerprint sensor locations, and wake and unlock via fingerprint. // Now we have fingerprint sensor locations, and wake and unlock via fingerprint.
val fingerprintLocation = Point(500, 500) val fingerprintLocation = Point(500, 500)

View File

@@ -70,8 +70,7 @@ class MediaTttUtilsTest : SysuiTestCase() {
context, context,
appPackageName = null, appPackageName = null,
isReceiver = false, isReceiver = false,
) { ) {}
}
assertThat(iconInfo.isAppIcon).isFalse() assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context)) assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -86,8 +85,7 @@ class MediaTttUtilsTest : SysuiTestCase() {
context, context,
appPackageName = null, appPackageName = null,
isReceiver = true, isReceiver = true,
) { ) {}
}
assertThat(iconInfo.isAppIcon).isFalse() assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context)) assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -119,8 +117,7 @@ class MediaTttUtilsTest : SysuiTestCase() {
context, context,
appPackageName = "fakePackageName", appPackageName = "fakePackageName",
isReceiver = false, isReceiver = false,
) { ) {}
}
assertThat(iconInfo.isAppIcon).isFalse() assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context)) assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -135,8 +132,7 @@ class MediaTttUtilsTest : SysuiTestCase() {
context, context,
appPackageName = "fakePackageName", appPackageName = "fakePackageName",
isReceiver = true, isReceiver = true,
) { ) {}
}
assertThat(iconInfo.isAppIcon).isFalse() assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context)) assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -154,7 +150,9 @@ class MediaTttUtilsTest : SysuiTestCase() {
context, context,
appPackageName = "fakePackageName", appPackageName = "fakePackageName",
isReceiver = false isReceiver = false
) { exceptionTriggered = true } ) {
exceptionTriggered = true
}
assertThat(exceptionTriggered).isTrue() assertThat(exceptionTriggered).isTrue()
} }
@@ -167,7 +165,9 @@ class MediaTttUtilsTest : SysuiTestCase() {
context, context,
appPackageName = "fakePackageName", appPackageName = "fakePackageName",
isReceiver = true isReceiver = true
) { exceptionTriggered = true } ) {
exceptionTriggered = true
}
assertThat(exceptionTriggered).isTrue() assertThat(exceptionTriggered).isTrue()
} }
@@ -179,8 +179,7 @@ class MediaTttUtilsTest : SysuiTestCase() {
context, context,
PACKAGE_NAME, PACKAGE_NAME,
isReceiver = false, isReceiver = false,
) { ) {}
}
assertThat(iconInfo.isAppIcon).isTrue() assertThat(iconInfo.isAppIcon).isTrue()
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName)) assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName))
@@ -194,8 +193,7 @@ class MediaTttUtilsTest : SysuiTestCase() {
context, context,
PACKAGE_NAME, PACKAGE_NAME,
isReceiver = true, isReceiver = true,
) { ) {}
}
assertThat(iconInfo.isAppIcon).isTrue() assertThat(iconInfo.isAppIcon).isTrue()
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName)) assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName))

View File

@@ -239,6 +239,7 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
* list2 = [false, true] * list2 = [false, true]
* list3 = [a, b, c] * list3 = [a, b, c]
* ``` * ```
*
* We'll generate test cases for: * We'll generate test cases for:
* *
* Test (1, false, a) Test (2, false, a) Test (3, false, a) Test (1, true, a) Test (1, * Test (1, false, a) Test (2, false, a) Test (3, false, a) Test (1, true, a) Test (1,

View File

@@ -29,6 +29,7 @@ import kotlinx.coroutines.test.runCurrent
/** /**
* Collect [flow] in a new [Job] and return a getter for the last collected value. * Collect [flow] in a new [Job] and return a getter for the last collected value.
*
* ``` * ```
* fun myTest() = runTest { * fun myTest() = runTest {
* // ... * // ...

View File

@@ -47,6 +47,7 @@ constructor(source: UnfoldTransitionProgressProvider? = null) :
/** /**
* Sets the source for the unfold transition progress updates. Replaces current provider if it * Sets the source for the unfold transition progress updates. Replaces current provider if it
* is already set * is already set
*
* @param provider transition provider that emits transition progress updates * @param provider transition provider that emits transition progress updates
*/ */
fun setSourceProvider(provider: UnfoldTransitionProgressProvider?) { fun setSourceProvider(provider: UnfoldTransitionProgressProvider?) {