First approach is more performant than other ones because [RenderEffect] forces an
- * intermediate render pass of the View to a texture to feed into it.
- *
- *
If going with the first approach, your custom [View] would look like as follow:
- *
If going with the second approach, it doesn't require an extra custom [View], and it is as
- * simple as calling [View.setRenderEffect] followed by [View.invalidate]. You can also chain the
- * effect with other [RenderEffect].
- *
- *
Third approach is an option, but it's more of a boilerplate so you would like to stick with
- * the second option. If you want to go with this option for some reason, below is the example:
- *
{
- return arrayOf(
- turbulenceNoiseShader.noiseOffsetX,
- turbulenceNoiseShader.noiseOffsetY,
- turbulenceNoiseShader.noiseOffsetZ
- )
- }
-
- private fun playEaseIn() {
- if (state != AnimationState.NOT_PLAYING) {
- return
- }
- state = AnimationState.EASE_IN
-
- val animator = ValueAnimator.ofFloat(0f, 1f)
- animator.duration = config.easeInDuration.toLong()
-
- // Animation should start from the initial position to avoid abrupt transition.
- val initialX = turbulenceNoiseShader.noiseOffsetX
- val initialY = turbulenceNoiseShader.noiseOffsetY
- val initialZ = turbulenceNoiseShader.noiseOffsetZ
-
- animator.addUpdateListener { updateListener ->
- val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
- val progress = updateListener.animatedValue as Float
-
- turbulenceNoiseShader.setNoiseMove(
- initialX + timeInSec * config.noiseMoveSpeedX,
- initialY + timeInSec * config.noiseMoveSpeedY,
- initialZ + timeInSec * config.noiseMoveSpeedZ
- )
-
- // TODO: Replace it with a better curve.
- turbulenceNoiseShader.setOpacity(progress * config.luminosityMultiplier)
-
- draw()
- }
-
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- currentAnimator = null
- playMain()
- }
- }
- )
-
- animator.start()
- this.currentAnimator = animator
- }
-
- private fun playMain() {
- if (state != AnimationState.EASE_IN) {
- return
- }
- state = AnimationState.MAIN
-
- val animator = ValueAnimator.ofFloat(0f, 1f)
- animator.duration = config.maxDuration.toLong()
-
- // Animation should start from the initial position to avoid abrupt transition.
- val initialX = turbulenceNoiseShader.noiseOffsetX
- val initialY = turbulenceNoiseShader.noiseOffsetY
- val initialZ = turbulenceNoiseShader.noiseOffsetZ
-
- turbulenceNoiseShader.setOpacity(config.luminosityMultiplier)
-
- animator.addUpdateListener { updateListener ->
- val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
- turbulenceNoiseShader.setNoiseMove(
- initialX + timeInSec * config.noiseMoveSpeedX,
- initialY + timeInSec * config.noiseMoveSpeedY,
- initialZ + timeInSec * config.noiseMoveSpeedZ
- )
-
- draw()
- }
-
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- currentAnimator = null
- playEaseOut()
- }
- }
- )
-
- animator.start()
- this.currentAnimator = animator
- }
-
- private fun playEaseOut() {
- if (state != AnimationState.MAIN) {
- return
- }
- state = AnimationState.EASE_OUT
-
- val animator = ValueAnimator.ofFloat(0f, 1f)
- animator.duration = config.easeOutDuration.toLong()
-
- // Animation should start from the initial position to avoid abrupt transition.
- val initialX = turbulenceNoiseShader.noiseOffsetX
- val initialY = turbulenceNoiseShader.noiseOffsetY
- val initialZ = turbulenceNoiseShader.noiseOffsetZ
-
- animator.addUpdateListener { updateListener ->
- val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
- val progress = updateListener.animatedValue as Float
-
- turbulenceNoiseShader.setNoiseMove(
- initialX + timeInSec * config.noiseMoveSpeedX,
- initialY + timeInSec * config.noiseMoveSpeedY,
- initialZ + timeInSec * config.noiseMoveSpeedZ
- )
-
- // TODO: Replace it with a better curve.
- turbulenceNoiseShader.setOpacity((1f - progress) * config.luminosityMultiplier)
-
- draw()
- }
-
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- currentAnimator = null
- state = AnimationState.NOT_PLAYING
- }
- }
- )
-
- animator.start()
- this.currentAnimator = animator
- }
-
- private fun draw() {
- paintCallback?.onDraw(paint!!)
- renderEffectCallback?.onDraw(
- RenderEffect.createRuntimeShaderEffect(
- turbulenceNoiseShader,
- TurbulenceNoiseShader.BACKGROUND_UNIFORM
- )
- )
- }
-
- /**
- * States of the loading effect animation.
- *
- * The state is designed to be follow the order below: [AnimationState.EASE_IN],
- * [AnimationState.MAIN], [AnimationState.EASE_OUT]. Note that ease in and out don't necessarily
- * mean the acceleration and deceleration in the animation curve. They simply mean each stage of
- * the animation. (i.e. Intro, core, and rest)
- */
- enum class AnimationState {
- EASE_IN,
- MAIN,
- EASE_OUT,
- NOT_PLAYING
- }
-
- /** Optional callback that is triggered when the animation state changes. */
- interface AnimationStateChangedCallback {
- /**
- * A callback that's triggered when the [AnimationState] changes. Example usage is
- * performing a cleanup when [AnimationState] becomes [NOT_PLAYING].
- */
- fun onStateChanged(oldState: AnimationState, newState: AnimationState) {}
- }
-
- private companion object {
- private const val MS_TO_SEC = 0.001f
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectView.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectView.kt
deleted file mode 100644
index aad593eb6a..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectView.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.loadingeffect
-
-import android.content.Context
-import android.graphics.BlendMode
-import android.graphics.Canvas
-import android.graphics.Paint
-import android.util.AttributeSet
-import android.view.View
-
-/** Custom View for drawing the [LoadingEffect] with [Canvas.drawPaint]. */
-open class LoadingEffectView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
-
- private var paint: Paint? = null
- private var blendMode: BlendMode = BlendMode.SRC_OVER
-
- override fun onDraw(canvas: Canvas) {
- if (!canvas.isHardwareAccelerated) {
- return
- }
- paint?.let { canvas.drawPaint(it) }
- }
-
- /** Designed to be called on [LoadingEffect.PaintDrawCallback.onDraw]. */
- fun draw(paint: Paint) {
- this.paint = paint
- this.paint!!.blendMode = blendMode
-
- invalidate()
- }
-
- /** Sets the blend mode of the [Paint]. */
- fun setBlendMode(blendMode: BlendMode) {
- this.blendMode = blendMode
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt
deleted file mode 100644
index d8e17c9c82..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.ripple
-
-import androidx.annotation.VisibleForTesting
-
-/** Controller that handles playing [RippleAnimation]. */
-class MultiRippleController(private val multipleRippleView: MultiRippleView) {
-
- companion object {
- /** Max number of ripple animations at a time. */
- @VisibleForTesting const val MAX_RIPPLE_NUMBER = 10
- }
-
- /** Updates all the ripple colors during the animation. */
- fun updateColor(color: Int) {
- multipleRippleView.ripples.forEach { anim -> anim.updateColor(color) }
- }
-
- fun play(rippleAnimation: RippleAnimation) {
- if (multipleRippleView.ripples.size >= MAX_RIPPLE_NUMBER) {
- return
- }
-
- multipleRippleView.ripples.add(rippleAnimation)
-
- rippleAnimation.play {
- // Remove ripple once the animation is done
- multipleRippleView.ripples.remove(rippleAnimation)
- }
-
- // Trigger drawing
- multipleRippleView.invalidate()
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/MultiRippleView.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/MultiRippleView.kt
deleted file mode 100644
index 6c175ddf1e..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/MultiRippleView.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.ripple
-
-import android.content.Context
-import android.graphics.Canvas
-import android.graphics.Paint
-import android.util.AttributeSet
-import android.view.View
-import androidx.annotation.VisibleForTesting
-
-/**
- * A view that allows multiple ripples to play.
- *
- * Use [MultiRippleController] to play ripple animations.
- */
-class MultiRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
-
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- val ripples = ArrayList()
- private val ripplePaint = Paint()
-
- companion object {
- private const val TAG = "MultiRippleView"
- }
-
- override fun onDraw(canvas: Canvas) {
- if (!canvas.isHardwareAccelerated) {
- // Drawing with the ripple shader requires hardware acceleration, so skip if it's
- // unsupported.
- return
- }
-
- var shouldInvalidate = false
-
- ripples.forEach { anim ->
- ripplePaint.shader = anim.rippleShader
- canvas.drawPaint(ripplePaint)
-
- shouldInvalidate = shouldInvalidate || anim.isPlaying()
- }
-
- if (shouldInvalidate) {
- invalidate()
- }
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
deleted file mode 100644
index d4372507e2..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.ripple
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.ValueAnimator
-import androidx.annotation.VisibleForTesting
-import androidx.core.graphics.ColorUtils
-
-/** A single ripple animation. */
-class RippleAnimation(private val config: RippleAnimationConfig) {
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- val rippleShader: RippleShader = RippleShader(config.rippleShape)
- private val animator: ValueAnimator = ValueAnimator.ofFloat(0f, 1f)
-
- init {
- applyConfigToShader()
- }
-
- /** Updates the ripple color during the animation. */
- fun updateColor(color: Int) {
- config.apply { config.color = color }
- applyConfigToShader()
- }
-
- @JvmOverloads
- fun play(onAnimationEnd: Runnable? = null) {
- if (isPlaying()) {
- return // Ignore if ripple effect is already playing
- }
-
- animator.duration = config.duration
- animator.addUpdateListener { updateListener ->
- val now = updateListener.currentPlayTime
- val progress = updateListener.animatedValue as Float
- rippleShader.rawProgress = progress
- rippleShader.distortionStrength = if (config.shouldDistort) 1 - progress else 0f
- rippleShader.time = now.toFloat()
- }
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- onAnimationEnd?.run()
- }
- }
- )
- animator.start()
- }
-
- /** Indicates whether the animation is playing. */
- fun isPlaying(): Boolean = animator.isRunning
-
- private fun applyConfigToShader() {
- with(rippleShader) {
- setCenter(config.centerX, config.centerY)
- rippleSize.setMaxSize(config.maxWidth, config.maxHeight)
- pixelDensity = config.pixelDensity
- color = ColorUtils.setAlphaComponent(config.color, config.opacity)
- sparkleStrength = config.sparkleStrength
-
- assignFadeParams(baseRingFadeParams, config.baseRingFadeParams)
- assignFadeParams(sparkleRingFadeParams, config.sparkleRingFadeParams)
- assignFadeParams(centerFillFadeParams, config.centerFillFadeParams)
- }
- }
-
- private fun assignFadeParams(
- destFadeParams: RippleShader.FadeParams,
- srcFadeParams: RippleShader.FadeParams?
- ) {
- srcFadeParams?.let {
- destFadeParams.fadeInStart = it.fadeInStart
- destFadeParams.fadeInEnd = it.fadeInEnd
- destFadeParams.fadeOutStart = it.fadeOutStart
- destFadeParams.fadeOutEnd = it.fadeOutEnd
- }
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt
deleted file mode 100644
index 91c0a5b635..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.android.systemui.surfaceeffects.ripple
-
-import android.graphics.Color
-
-/**
- * A struct that holds the ripple animation configurations.
- *
- * This configuration is designed to play a SINGLE animation. Do not reuse or modify the
- * configuration parameters to play different animations, unless the value has to change within the
- * single animation (e.g. Change color or opacity during the animation). Note that this data class
- * is pulled out to make the [RippleAnimation] constructor succinct.
- */
-data class RippleAnimationConfig(
- val rippleShape: RippleShader.RippleShape = RippleShader.RippleShape.CIRCLE,
- val duration: Long = 0L,
- val centerX: Float = 0f,
- val centerY: Float = 0f,
- val maxWidth: Float = 0f,
- val maxHeight: Float = 0f,
- val pixelDensity: Float = 1f,
- var color: Int = Color.WHITE,
- val opacity: Int = RippleShader.RIPPLE_DEFAULT_ALPHA,
- val sparkleStrength: Float = RippleShader.RIPPLE_SPARKLE_STRENGTH,
- // Null means it uses default fade parameter values.
- val baseRingFadeParams: RippleShader.FadeParams? = null,
- val sparkleRingFadeParams: RippleShader.FadeParams? = null,
- val centerFillFadeParams: RippleShader.FadeParams? = null,
- val shouldDistort: Boolean = true
-)
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
deleted file mode 100644
index 7e56f4b3d2..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.ripple
-
-import android.graphics.RuntimeShader
-import android.util.Log
-import android.view.animation.Interpolator
-import android.view.animation.PathInterpolator
-import androidx.annotation.VisibleForTesting
-import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary
-import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
-
-/**
- * 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
- * 2. an expanding ring that appears throughout the effect
- * 3. an expanding ring-shaped area that reveals noise over #2.
- *
- * The ripple shader will be default to the circle shape if not specified.
- *
- * Modeled after frameworks/base/graphics/java/android/graphics/drawable/RippleShader.java.
- */
-class RippleShader(rippleShape: RippleShape = RippleShape.CIRCLE) :
- RuntimeShader(buildShader(rippleShape)) {
-
- /** Shapes that the [RippleShader] supports. */
- enum class RippleShape {
- CIRCLE,
- ROUNDED_BOX,
- ELLIPSE
- }
- // language=AGSL
- companion object {
- private val TAG = RippleShader::class.simpleName
-
- // Default fade in/ out values. The value range is [0,1].
- const val DEFAULT_FADE_IN_START = 0f
- const val DEFAULT_FADE_OUT_END = 1f
-
- const val DEFAULT_BASE_RING_FADE_IN_END = 0.1f
- const val DEFAULT_BASE_RING_FADE_OUT_START = 0.3f
-
- const val DEFAULT_SPARKLE_RING_FADE_IN_END = 0.1f
- const val DEFAULT_SPARKLE_RING_FADE_OUT_START = 0.4f
-
- const val DEFAULT_CENTER_FILL_FADE_IN_END = 0f
- const val DEFAULT_CENTER_FILL_FADE_OUT_START = 0f
- const val DEFAULT_CENTER_FILL_FADE_OUT_END = 0.6f
-
- const val RIPPLE_SPARKLE_STRENGTH: Float = 0.3f
- const val RIPPLE_DEFAULT_COLOR: Int = 0xffffffff.toInt()
- const val RIPPLE_DEFAULT_ALPHA: Int = 115 // full opacity is 255.
-
- private const val SHADER_UNIFORMS =
- """
- uniform vec2 in_center;
- uniform vec2 in_size;
- uniform float in_cornerRadius;
- uniform float in_thickness;
- uniform float in_time;
- uniform float in_distort_radial;
- uniform float in_distort_xy;
- uniform float in_fadeSparkle;
- uniform float in_fadeFill;
- uniform float in_fadeRing;
- uniform float in_blur;
- uniform float in_pixelDensity;
- layout(color) uniform vec4 in_color;
- uniform float in_sparkle_strength;
- """
-
- private const val SHADER_CIRCLE_MAIN =
- """
- vec4 main(vec2 p) {
- vec2 p_distorted = distort(p, in_time, in_distort_radial, in_distort_xy);
- float radius = in_size.x * 0.5;
- float sparkleRing = soften(circleRing(p_distorted-in_center, radius), in_blur);
- float inside = soften(sdCircle(p_distorted-in_center, radius * 1.25), in_blur);
- float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_time * 0.00175)
- * (1.-sparkleRing) * in_fadeSparkle;
-
- float rippleInsideAlpha = (1.-inside) * in_fadeFill;
- float rippleRingAlpha = (1.-sparkleRing) * in_fadeRing;
- float rippleAlpha = max(rippleInsideAlpha, rippleRingAlpha) * in_color.a;
- vec4 ripple = vec4(in_color.rgb, 1.0) * rippleAlpha;
- return mix(ripple, vec4(sparkle), sparkle * in_sparkle_strength);
- }
- """
-
- private const val SHADER_ROUNDED_BOX_MAIN =
- """
- vec4 main(vec2 p) {
- float sparkleRing = soften(roundedBoxRing(p-in_center, in_size, in_cornerRadius,
- in_thickness), in_blur);
- float inside = soften(sdRoundedBox(p-in_center, in_size * 1.25, in_cornerRadius),
- in_blur);
- float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_time * 0.00175)
- * (1.-sparkleRing) * in_fadeSparkle;
-
- float rippleInsideAlpha = (1.-inside) * in_fadeFill;
- float rippleRingAlpha = (1.-sparkleRing) * in_fadeRing;
- float rippleAlpha = max(rippleInsideAlpha, rippleRingAlpha) * in_color.a;
- vec4 ripple = vec4(in_color.rgb, 1.0) * rippleAlpha;
- return mix(ripple, vec4(sparkle), sparkle * in_sparkle_strength);
- }
- """
-
- private const val SHADER_ELLIPSE_MAIN =
- """
- vec4 main(vec2 p) {
- vec2 p_distorted = distort(p, in_time, in_distort_radial, in_distort_xy);
-
- float sparkleRing = soften(ellipseRing(p_distorted-in_center, in_size), in_blur);
- float inside = soften(sdEllipse(p_distorted-in_center, in_size * 1.2), in_blur);
- float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_time * 0.00175)
- * (1.-sparkleRing) * in_fadeSparkle;
-
- float rippleInsideAlpha = (1.-inside) * in_fadeFill;
- float rippleRingAlpha = (1.-sparkleRing) * in_fadeRing;
- float rippleAlpha = max(rippleInsideAlpha, rippleRingAlpha) * in_color.a;
- vec4 ripple = vec4(in_color.rgb, 1.0) * rippleAlpha;
- return mix(ripple, vec4(sparkle), sparkle * in_sparkle_strength);
- }
- """
-
- private const val CIRCLE_SHADER =
- SHADER_UNIFORMS +
- ShaderUtilLibrary.SHADER_LIB +
- SdfShaderLibrary.SHADER_SDF_OPERATION_LIB +
- SdfShaderLibrary.CIRCLE_SDF +
- SHADER_CIRCLE_MAIN
- private const val ROUNDED_BOX_SHADER =
- SHADER_UNIFORMS +
- ShaderUtilLibrary.SHADER_LIB +
- SdfShaderLibrary.SHADER_SDF_OPERATION_LIB +
- SdfShaderLibrary.ROUNDED_BOX_SDF +
- SHADER_ROUNDED_BOX_MAIN
- private const val ELLIPSE_SHADER =
- SHADER_UNIFORMS +
- ShaderUtilLibrary.SHADER_LIB +
- SdfShaderLibrary.SHADER_SDF_OPERATION_LIB +
- SdfShaderLibrary.ELLIPSE_SDF +
- SHADER_ELLIPSE_MAIN
-
- private fun buildShader(rippleShape: RippleShape): String =
- when (rippleShape) {
- RippleShape.CIRCLE -> CIRCLE_SHADER
- RippleShape.ROUNDED_BOX -> ROUNDED_BOX_SHADER
- RippleShape.ELLIPSE -> ELLIPSE_SHADER
- }
-
- private fun subProgress(start: Float, end: Float, progress: Float): Float {
- // Avoid division by 0.
- if (start == end) {
- // If start and end are the same and progress has exceeded the start/ end point,
- // treat it as 1, otherwise 0.
- return if (progress > start) 1f else 0f
- }
-
- val min = Math.min(start, end)
- val max = Math.max(start, end)
- val sub = Math.min(Math.max(progress, min), max)
- return (sub - start) / (end - start)
- }
-
- private fun getFade(fadeParams: FadeParams, rawProgress: Float): Float {
- val fadeIn = subProgress(fadeParams.fadeInStart, fadeParams.fadeInEnd, rawProgress)
- val fadeOut =
- 1f - subProgress(fadeParams.fadeOutStart, fadeParams.fadeOutEnd, rawProgress)
-
- return Math.min(fadeIn, fadeOut)
- }
-
- private fun lerp(start: Float, stop: Float, amount: Float): Float {
- return start + (stop - start) * amount
- }
-
- // Copied from [Interpolators#STANDARD]. This is to remove dependency on AnimationLib.
- private val STANDARD: Interpolator = PathInterpolator(0.2f, 0f, 0f, 1f)
- }
-
- /** Sets the center position of the ripple. */
- fun setCenter(x: Float, y: Float) {
- setFloatUniform("in_center", x, y)
- }
-
- /**
- * Blur multipliers for the ripple.
- *
- *
It interpolates from [blurStart] to [blurEnd] based on the [progress]. Increase number to
- * add more blur.
- */
- var blurStart: Float = 1.25f
- var blurEnd: Float = 0.5f
-
- /** Size of the ripple. */
- val rippleSize = RippleSize()
-
- /**
- * Linear progress of the ripple. Float value between [0, 1].
- *
- *
Note that the progress here is expected to be linear without any curve applied.
- */
- var rawProgress: Float = 0.0f
- set(value) {
- field = value
- progress = STANDARD.getInterpolation(value)
-
- setFloatUniform("in_fadeSparkle", getFade(sparkleRingFadeParams, value))
- setFloatUniform("in_fadeRing", getFade(baseRingFadeParams, value))
- setFloatUniform("in_fadeFill", getFade(centerFillFadeParams, value))
- }
-
- /** Progress with Standard easing curve applied. */
- private var progress: Float = 0.0f
- set(value) {
- field = value
-
- rippleSize.update(value)
-
- setFloatUniform("in_size", rippleSize.currentWidth, rippleSize.currentHeight)
- setFloatUniform("in_thickness", rippleSize.currentHeight * 0.5f)
- // Corner radius is always max of the min between the current width and height.
- setFloatUniform(
- "in_cornerRadius",
- Math.min(rippleSize.currentWidth, rippleSize.currentHeight)
- )
- setFloatUniform("in_blur", lerp(1.25f, 0.5f, value))
- }
-
- /** Play time since the start of the effect. */
- var time: Float = 0.0f
- set(value) {
- field = value
- setFloatUniform("in_time", value)
- }
-
- /** A hex value representing the ripple color, in the format of ARGB */
- var color: Int = 0xffffff
- set(value) {
- field = value
- setColorUniform("in_color", value)
- }
-
- /**
- * Noise sparkle intensity. Expected value between [0, 1]. The sparkle is white, and thus with
- * strength 0 it's transparent, leaving the ripple fully smooth, while with strength 1 it's
- * opaque white and looks the most grainy.
- */
- var sparkleStrength: Float = 0.0f
- set(value) {
- field = value
- setFloatUniform("in_sparkle_strength", value)
- }
-
- /** Distortion strength of the ripple. Expected value between[0, 1]. */
- var distortionStrength: Float = 0.0f
- set(value) {
- field = value
- setFloatUniform("in_distort_radial", 75 * rawProgress * value)
- setFloatUniform("in_distort_xy", 75 * value)
- }
-
- /**
- * Pixel density of the screen that the effects are rendered to.
- *
- *
This value should come from [resources.displayMetrics.density].
- */
- var pixelDensity: Float = 1.0f
- set(value) {
- field = value
- setFloatUniform("in_pixelDensity", value)
- }
-
- /** Parameters that are used to fade in/ out of the sparkle ring. */
- val sparkleRingFadeParams =
- FadeParams(
- DEFAULT_FADE_IN_START,
- DEFAULT_SPARKLE_RING_FADE_IN_END,
- DEFAULT_SPARKLE_RING_FADE_OUT_START,
- DEFAULT_FADE_OUT_END
- )
-
- /**
- * Parameters that are used to fade in/ out of the base ring.
- *
- *
Note that the shader draws the sparkle ring on top of the base ring.
- */
- val baseRingFadeParams =
- FadeParams(
- DEFAULT_FADE_IN_START,
- DEFAULT_BASE_RING_FADE_IN_END,
- DEFAULT_BASE_RING_FADE_OUT_START,
- DEFAULT_FADE_OUT_END
- )
-
- /** Parameters that are used to fade in/ out of the center fill. */
- val centerFillFadeParams =
- FadeParams(
- DEFAULT_FADE_IN_START,
- DEFAULT_CENTER_FILL_FADE_IN_END,
- DEFAULT_CENTER_FILL_FADE_OUT_START,
- DEFAULT_CENTER_FILL_FADE_OUT_END
- )
-
- /**
- * Parameters used for fade in and outs of the ripple.
- *
- *
Note that all the fade in/ outs are "linear" progression.
- *
- * ```
- * (opacity)
- * 1
- * │
- * maxAlpha ← ――――――――――――
- * │ / \
- * │ / \
- * minAlpha ←――――/ \―――― (alpha change)
- * │
- * │
- * 0 ―――↑―――↑―――――――――↑―――↑――――1 (progress)
- * fadeIn fadeOut
- * Start & End Start & End
- * ```
- *
- *
If no fade in/ out is needed, set [fadeInStart] and [fadeInEnd] to 0; [fadeOutStart] and
- * [fadeOutEnd] to 1.
- */
- data class FadeParams(
- /**
- * The starting point of the fade out which ends at [fadeInEnd], given that the animation
- * goes from 0 to 1.
- */
- var fadeInStart: Float = DEFAULT_FADE_IN_START,
- /**
- * The endpoint of the fade in when the fade in starts at [fadeInStart], given that the
- * animation goes from 0 to 1.
- */
- var fadeInEnd: Float,
- /**
- * The starting point of the fade out which ends at 1, given that the animation goes from 0
- * to 1.
- */
- var fadeOutStart: Float,
-
- /** The endpoint of the fade out, given that the animation goes from 0 to 1. */
- var fadeOutEnd: Float = DEFAULT_FADE_OUT_END,
- )
-
- /**
- * Desired size of the ripple at a point t in [progress].
- *
- *
Note that [progress] is curved and normalized. Below is an example usage:
- * SizeAtProgress(t= 0f, width= 0f, height= 0f), SizeAtProgress(t= 0.2f, width= 500f, height=
- * 700f), SizeAtProgress(t= 1f, width= 100f, height= 300f)
- *
- *
For simple ripple effects, you will want to use [setMaxSize] as it is translated into:
- * SizeAtProgress(t= 0f, width= 0f, height= 0f), SizeAtProgress(t= 1f, width= maxWidth, height=
- * maxHeight)
- */
- data class SizeAtProgress(
- /** Time t in [0,1] progress range. */
- var t: Float,
- /** Target width size of the ripple at time [t]. */
- var width: Float,
- /** Target height size of the ripple at time [t]. */
- var height: Float
- )
-
- /** Updates and stores the ripple size. */
- inner class RippleSize {
- @VisibleForTesting var sizes = mutableListOf()
- @VisibleForTesting var currentSizeIndex = 0
- @VisibleForTesting val initialSize = SizeAtProgress(0f, 0f, 0f)
-
- var currentWidth: Float = 0f
- private set
- var currentHeight: Float = 0f
- private set
-
- /**
- * Sets the max size of the ripple.
- *
- * Use this if the ripple shape simply changes linearly.
- */
- fun setMaxSize(width: Float, height: Float) {
- setSizeAtProgresses(initialSize, SizeAtProgress(1f, width, height))
- }
-
- /**
- * Sets the list of [sizes].
- *
- *
Note that setting this clears the existing sizes.
- */
- fun setSizeAtProgresses(vararg sizes: SizeAtProgress) {
- // Reset everything.
- this.sizes.clear()
- currentSizeIndex = 0
-
- this.sizes.addAll(sizes)
- this.sizes.sortBy { it.t }
- }
-
- /**
- * Updates the current ripple size based on the progress.
- *
- *
Should be called when progress updates.
- */
- fun update(progress: Float) {
- val targetIndex = updateTargetIndex(progress)
- val prevIndex = Math.max(targetIndex - 1, 0)
-
- val targetSize = sizes[targetIndex]
- val prevSize = sizes[prevIndex]
-
- val subProgress = subProgress(prevSize.t, targetSize.t, progress)
-
- currentWidth = targetSize.width * subProgress + prevSize.width
- currentHeight = targetSize.height * subProgress + prevSize.height
- }
-
- private fun updateTargetIndex(progress: Float): Int {
- if (sizes.isEmpty()) {
- // It could be empty on init.
- if (progress > 0f) {
- Log.e(
- TAG,
- "Did you forget to set the ripple size? Use [setMaxSize] or " +
- "[setSizeAtProgresses] before playing the animation."
- )
- }
- // If there's no size is set, we set everything to 0 and return early.
- setSizeAtProgresses(initialSize)
- return currentSizeIndex
- }
-
- var candidate = sizes[currentSizeIndex]
-
- while (progress > candidate.t) {
- currentSizeIndex = Math.min(currentSizeIndex + 1, sizes.size - 1)
- candidate = sizes[currentSizeIndex]
- }
-
- return currentSizeIndex
- }
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
deleted file mode 100644
index b899127095..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.ripple
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.ValueAnimator
-import android.content.Context
-import android.content.res.Configuration
-import android.graphics.Canvas
-import android.graphics.Paint
-import android.util.AttributeSet
-import android.view.View
-import androidx.core.graphics.ColorUtils
-import com.android.systemui.surfaceeffects.ripple.RippleShader.RippleShape
-
-/**
- * A generic expanding ripple effect.
- *
- * Set up the shader with a desired [RippleShape] using [setupShader], [setMaxSize] and [setCenter],
- * then call [startRipple] to trigger the ripple expansion.
- */
-open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
-
- protected lateinit var rippleShader: RippleShader
- lateinit var rippleShape: RippleShape
- private set
-
- private val ripplePaint = Paint()
- protected val animator: ValueAnimator = ValueAnimator.ofFloat(0f, 1f)
-
- var duration: Long = 1750
-
- fun setMaxSize(maxWidth: Float, maxHeight: Float) {
- rippleShader.rippleSize.setMaxSize(maxWidth, maxHeight)
- }
-
- private var centerX: Float = 0.0f
- private var centerY: Float = 0.0f
- fun setCenter(x: Float, y: Float) {
- this.centerX = x
- this.centerY = y
- rippleShader.setCenter(x, y)
- }
-
- override fun onConfigurationChanged(newConfig: Configuration?) {
- rippleShader.pixelDensity = resources.displayMetrics.density
- super.onConfigurationChanged(newConfig)
- }
-
- override fun onAttachedToWindow() {
- rippleShader.pixelDensity = resources.displayMetrics.density
- super.onAttachedToWindow()
- }
-
- /** Initializes the shader. Must be called before [startRipple]. */
- fun setupShader(rippleShape: RippleShape = RippleShape.CIRCLE) {
- this.rippleShape = rippleShape
- rippleShader = RippleShader(rippleShape)
-
- rippleShader.color = RippleShader.RIPPLE_DEFAULT_COLOR
- rippleShader.rawProgress = 0f
- rippleShader.sparkleStrength = RippleShader.RIPPLE_SPARKLE_STRENGTH
- rippleShader.pixelDensity = resources.displayMetrics.density
-
- ripplePaint.shader = rippleShader
- }
-
- /**
- * Sets the fade parameters for the base ring.
- *
- *
Base ring indicates a blurred ring below the sparkle ring. See
- * [RippleShader.baseRingFadeParams].
- */
- @JvmOverloads
- fun setBaseRingFadeParams(
- fadeInStart: Float = rippleShader.baseRingFadeParams.fadeInStart,
- fadeInEnd: Float = rippleShader.baseRingFadeParams.fadeInEnd,
- fadeOutStart: Float = rippleShader.baseRingFadeParams.fadeOutStart,
- fadeOutEnd: Float = rippleShader.baseRingFadeParams.fadeOutEnd
- ) {
- setFadeParams(
- rippleShader.baseRingFadeParams,
- fadeInStart,
- fadeInEnd,
- fadeOutStart,
- fadeOutEnd
- )
- }
-
- /**
- * Sets the fade parameters for the sparkle ring.
- *
- *
Sparkle ring refers to the ring that's drawn on top of the base ring. See
- * [RippleShader.sparkleRingFadeParams].
- */
- @JvmOverloads
- fun setSparkleRingFadeParams(
- fadeInStart: Float = rippleShader.sparkleRingFadeParams.fadeInStart,
- fadeInEnd: Float = rippleShader.sparkleRingFadeParams.fadeInEnd,
- fadeOutStart: Float = rippleShader.sparkleRingFadeParams.fadeOutStart,
- fadeOutEnd: Float = rippleShader.sparkleRingFadeParams.fadeOutEnd
- ) {
- setFadeParams(
- rippleShader.sparkleRingFadeParams,
- fadeInStart,
- fadeInEnd,
- fadeOutStart,
- fadeOutEnd
- )
- }
-
- /**
- * Sets the fade parameters for the center fill.
- *
- *
One common use case is set all the params to 1, which completely removes the center fill.
- * See [RippleShader.centerFillFadeParams].
- */
- @JvmOverloads
- fun setCenterFillFadeParams(
- fadeInStart: Float = rippleShader.centerFillFadeParams.fadeInStart,
- fadeInEnd: Float = rippleShader.centerFillFadeParams.fadeInEnd,
- fadeOutStart: Float = rippleShader.centerFillFadeParams.fadeOutStart,
- fadeOutEnd: Float = rippleShader.centerFillFadeParams.fadeOutEnd
- ) {
- setFadeParams(
- rippleShader.centerFillFadeParams,
- fadeInStart,
- fadeInEnd,
- fadeOutStart,
- fadeOutEnd
- )
- }
-
- private fun setFadeParams(
- fadeParams: RippleShader.FadeParams,
- fadeInStart: Float,
- fadeInEnd: Float,
- fadeOutStart: Float,
- fadeOutEnd: Float
- ) {
- with(fadeParams) {
- this.fadeInStart = fadeInStart
- this.fadeInEnd = fadeInEnd
- this.fadeOutStart = fadeOutStart
- this.fadeOutEnd = fadeOutEnd
- }
- }
-
- /**
- * Sets blur multiplier at start and end of the progress.
- *
- *
It interpolates between [start] and [end]. No need to set it if using default blur.
- */
- fun setBlur(start: Float, end: Float) {
- rippleShader.blurStart = start
- rippleShader.blurEnd = end
- }
-
- /**
- * Sets the list of [RippleShader.SizeAtProgress].
- *
- *
Note that this clears the list before it sets with the new data.
- */
- fun setSizeAtProgresses(vararg targetSizes: RippleShader.SizeAtProgress) {
- rippleShader.rippleSize.setSizeAtProgresses(*targetSizes)
- }
-
- @JvmOverloads
- fun startRipple(onAnimationEnd: Runnable? = null) {
- if (animator.isRunning) {
- return // Ignore if ripple effect is already playing
- }
- animator.duration = duration
- animator.addUpdateListener { updateListener ->
- val now = updateListener.currentPlayTime
- val progress = updateListener.animatedValue as Float
- rippleShader.rawProgress = progress
- rippleShader.distortionStrength = 1 - progress
- rippleShader.time = now.toFloat()
- invalidate()
- }
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- onAnimationEnd?.run()
- }
- }
- )
- animator.start()
- }
-
- /**
- * Set the color to be used for the ripple.
- *
- * The alpha value of the color will be applied to the ripple. The alpha range is [0-255].
- */
- fun setColor(color: Int, alpha: Int = RippleShader.RIPPLE_DEFAULT_ALPHA) {
- rippleShader.color = ColorUtils.setAlphaComponent(color, alpha)
- }
-
- /** Set the intensity of the sparkles. */
- fun setSparkleStrength(strength: Float) {
- rippleShader.sparkleStrength = strength
- }
-
- /** Indicates whether the ripple animation is playing. */
- fun rippleInProgress(): Boolean = animator.isRunning
-
- override fun onDraw(canvas: Canvas) {
- if (!canvas.isHardwareAccelerated) {
- // Drawing with the ripple shader requires hardware acceleration, so skip if it's
- // unsupported.
- return
- }
- // To reduce overdraw, we mask the effect to a circle or a rectangle that's bigger than the
- // active effect area. Values here should be kept in sync with the animation implementation
- // in the ripple shader.
- if (rippleShape == RippleShape.CIRCLE) {
- val maskRadius = rippleShader.rippleSize.currentWidth
- canvas.drawCircle(centerX, centerY, maskRadius, ripplePaint)
- } else if (rippleShape == RippleShape.ELLIPSE) {
- val maskWidth = rippleShader.rippleSize.currentWidth * 2
- val maskHeight = rippleShader.rippleSize.currentHeight * 2
- canvas.drawRect(
- /* left= */ centerX - maskWidth,
- /* top= */ centerY - maskHeight,
- /* right= */ centerX + maskWidth,
- /* bottom= */ centerY + maskHeight,
- ripplePaint
- )
- } else { // RippleShape.RoundedBox
- // No masking for the rounded box, as it has more blur which requires larger bounds.
- // Masking creates sharp bounds even when the masking is 4 times bigger.
- canvas.drawPaint(ripplePaint)
- }
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt
deleted file mode 100644
index c94fad7246..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.shaders
-
-import android.graphics.RuntimeShader
-
-/** Simply renders a solid color. */
-class SolidColorShader(color: Int) : RuntimeShader(SHADER) {
- // language=AGSL
- private companion object {
- private const val SHADER =
- """
- layout(color) uniform vec4 in_color;
- vec4 main(vec2 p) {
- return in_color;
- }
- """
- }
-
- init {
- setColorUniform("in_color", color)
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt
deleted file mode 100644
index df07856e32..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.shaders
-
-import android.graphics.Color
-import android.graphics.RuntimeShader
-import android.graphics.Shader
-import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
-
-/**
- * Renders sparkles based on the luma matte.
- *
- * For example, you can pass in simplex noise as the luma matte and have a cloud looking sparkles.
- *
- * You may want to utilize this shader by: (Preferred) 1. Create a RuntimeShaderEffect and set the
- * [RenderEffect] to the target [View].
- * 2. Create a custom [View], set the shader to the [Paint] and use [Canvas.drawPaint] in [onDraw].
- */
-class SparkleShader : RuntimeShader(SPARKLE_SHADER) {
- // language=AGSL
- companion object {
- private const val UNIFORMS =
- """
- // Used it for RenderEffect. For example:
- // myView.setRenderEffect(
- // RenderEffect.createRuntimeShaderEffect(SparkleShader(), "in_src")
- // )
- uniform shader in_src;
- uniform half in_time;
- uniform half in_pixelate;
- uniform shader in_lumaMatte;
- layout(color) uniform vec4 in_color;
- """
- private const val MAIN_SHADER =
- """vec4 main(vec2 p) {
- half3 src = in_src.eval(p).rgb;
- half luma = getLuminosity(in_lumaMatte.eval(p).rgb);
- half sparkle = sparkles(p - mod(p, in_pixelate), in_time);
- half3 mask = maskLuminosity(in_color.rgb * sparkle, luma);
-
- return vec4(src * mask * in_color.a, in_color.a);
- }
- """
- private const val SPARKLE_SHADER = UNIFORMS + ShaderUtilLibrary.SHADER_LIB + MAIN_SHADER
-
- /** Highly recommended to use this value unless specified by design spec. */
- const val DEFAULT_SPARKLE_PIXELATE_AMOUNT = 0.8f
- }
-
- init {
- // Initializes the src and luma matte to be white.
- setInputShader("in_src", SolidColorShader(Color.WHITE))
- setLumaMatteColor(Color.WHITE)
- }
-
- /**
- * Sets the time of the sparkle animation.
- *
- * This is used for animating sparkles. Note that this only makes the sparkles sparkle in place.
- * In order to move the sparkles in x, y directions, move the luma matte input instead.
- */
- fun setTime(time: Float) {
- setFloatUniform("in_time", time)
- }
-
- /**
- * Sets pixelated amount of the sparkle.
- *
- * This value *must* be based on [resources.displayMetrics.density]. Otherwise, this will result
- * in having different sparkle sizes on different screens.
- *
- * Expected to be used as follows:
- *
- * {@code
- * val pixelDensity = context.resources.displayMetrics.density
- * // Sparkles will be 0.8 of the pixel size.
- * val sparkleShader = SparkleShader().apply { setPixelateAmount(pixelDensity * 0.8f) }
- * }
- *
- */
- fun setPixelateAmount(pixelateAmount: Float) {
- setFloatUniform("in_pixelate", pixelateAmount)
- }
-
- /**
- * Sets the luma matte for the sparkles. The luminosity determines the sparkle's visibility.
- * Useful for setting a complex mask (e.g. simplex noise, texture, etc.)
- */
- fun setLumaMatte(lumaMatte: Shader) {
- setInputShader("in_lumaMatte", lumaMatte)
- }
-
- /** Sets the luma matte for the sparkles. Useful for setting a solid color. */
- fun setLumaMatteColor(color: Int) {
- setInputShader("in_lumaMatte", SolidColorShader(color))
- }
-
- /** Sets the color of the sparkles. Expect to have the alpha value encoded. */
- fun setColor(color: Int) {
- setColorUniform("in_color", color)
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt
deleted file mode 100644
index 4efab58347..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.shaderutil
-
-/** Library class that contains 2D signed distance functions. */
-class SdfShaderLibrary {
- // language=AGSL
- companion object {
- const val CIRCLE_SDF =
- """
- float sdCircle(vec2 p, float r) {
- return (length(p)-r) / r;
- }
-
- float circleRing(vec2 p, float radius) {
- float thicknessHalf = radius * 0.25;
-
- float outerCircle = sdCircle(p, radius + thicknessHalf);
- float innerCircle = sdCircle(p, radius);
-
- return subtract(outerCircle, innerCircle);
- }
- """
-
- const val BOX_SDF =
- """
- float sdBox(vec2 p, vec2 size) {
- size = size * 0.5;
- vec2 d = abs(p) - size;
- return length(max(d, 0.)) + min(max(d.x, d.y), 0.) / size.y;
- }
- """
-
- const val ROUNDED_BOX_SDF =
- """
- float sdRoundedBox(vec2 p, vec2 size, float cornerRadius) {
- size *= 0.5;
- cornerRadius *= 0.5;
- vec2 d = abs(p) - size + cornerRadius;
-
- float outside = length(max(d, 0.0));
- float inside = min(max(d.x, d.y), 0.0);
-
- return (outside + inside - cornerRadius) / size.y;
- }
-
- float roundedBoxRing(vec2 p, vec2 size, float cornerRadius,
- float borderThickness) {
- float outerRoundBox = sdRoundedBox(p, size + vec2(borderThickness),
- cornerRadius + borderThickness);
- float innerRoundBox = sdRoundedBox(p, size, cornerRadius);
- return subtract(outerRoundBox, innerRoundBox);
- }
- """
-
- // Used non-trigonometry parametrization and Halley's method (iterative) for root finding.
- // This is more expensive than the regular circle SDF, recommend to use the circle SDF if
- // possible.
- const val ELLIPSE_SDF =
- """float sdEllipse(vec2 p, vec2 wh) {
- wh *= 0.5;
-
- // symmetry
- (wh.x > wh.y) ? wh = wh.yx, p = abs(p.yx) : p = abs(p);
-
- vec2 u = wh*p, v = wh*wh;
-
- float U1 = u.y/2.0;
- float U2 = v.y-v.x;
- float U3 = u.x-U2;
- float U4 = u.x+U2;
- float U5 = 4.0*U1;
- float U6 = 6.0*U1;
- float U7 = 3.0*U3;
-
- float t = 0.5;
- for (int i = 0; i < 3; i ++) {
- float F1 = t*(t*t*(U1*t+U3)+U4)-U1;
- float F2 = t*t*(U5*t+U7)+U4;
- float F3 = t*(U6*t+U7);
-
- t += (F1*F2)/(F1*F3-F2*F2);
- }
-
- t = clamp(t, 0.0, 1.0);
-
- float d = distance(p, wh*vec2(1.0-t*t,2.0*t)/(t*t+1.0));
- d /= wh.y;
-
- return (dot(p/wh,p/wh)>1.0) ? d : -d;
- }
-
- float ellipseRing(vec2 p, vec2 wh) {
- vec2 thicknessHalf = wh * 0.25;
-
- float outerEllipse = sdEllipse(p, wh + thicknessHalf);
- float innerEllipse = sdEllipse(p, wh);
-
- return subtract(outerEllipse, innerEllipse);
- }
- """
-
- const val SHADER_SDF_OPERATION_LIB =
- """
- float soften(float d, float blur) {
- float blurHalf = blur * 0.5;
- return smoothstep(-blurHalf, blurHalf, d);
- }
-
- float subtract(float outer, float inner) {
- return max(outer, -inner);
- }
- """
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
deleted file mode 100644
index 867bbb7d74..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.shaderutil
-
-/** Common utility functions that are used for computing shaders. */
-object ShaderUtilLibrary {
- // language=AGSL
- const val SHADER_LIB =
- """
- float triangleNoise(vec2 n) {
- n = fract(n * vec2(5.3987, 5.4421));
- n += dot(n.yx, n.xy + vec2(21.5351, 14.3137));
- float xy = n.x * n.y;
- // compute in [0..2[ and remap to [-1.0..1.0[
- return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
- }
-
- const float PI = 3.1415926535897932384626;
-
- float sparkles(vec2 uv, float t) {
- float n = triangleNoise(uv);
- float s = 0.0;
- for (float i = 0; i < 4; i += 1) {
- float l = i * 0.01;
- float h = l + 0.1;
- float o = smoothstep(n - l, h, n);
- o *= abs(sin(PI * o * (t + 0.55 * i)));
- s += o;
- }
- return s;
- }
-
- vec2 distort(vec2 p, float time, float distort_amount_radial,
- float distort_amount_xy) {
- float angle = atan(p.y, p.x);
- return p + vec2(sin(angle * 8 + time * 0.003 + 1.641),
- cos(angle * 5 + 2.14 + time * 0.00412)) * distort_amount_radial
- + vec2(sin(p.x * 0.01 + time * 0.00215 + 0.8123),
- cos(p.y * 0.01 + time * 0.005931)) * distort_amount_xy;
- }
-
- // Perceived luminosity (L′), not absolute luminosity.
- half getLuminosity(vec3 c) {
- return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
- }
-
- // Creates a luminosity mask and clamp to the legal range.
- vec3 maskLuminosity(vec3 dest, float lum) {
- dest.rgb *= vec3(lum);
- // Clip back into the legal range
- dest = clamp(dest, vec3(0.), vec3(1.0));
- return dest;
- }
-
- // Integer mod. GLSL es 1.0 doesn't have integer mod :(
- int imod(int a, int b) {
- return a - (b * (a / b));
- }
-
- ivec3 imod(ivec3 a, int b) {
- return ivec3(imod(a.x, b), imod(a.y, b), imod(a.z, b));
- }
-
- // Integer based hash function with the return range of [-1, 1].
- vec3 hash(vec3 p) {
- ivec3 v = ivec3(p);
- v = v * 1671731 + 10139267;
-
- v.x += v.y * v.z;
- v.y += v.z * v.x;
- v.z += v.x * v.y;
-
- ivec3 v2 = v / 65536; // v >> 16
- v = imod((10 - imod((v + v2), 10)), 10); // v ^ v2
-
- v.x += v.y * v.z;
- v.y += v.z * v.x;
- v.z += v.x * v.y;
-
- // Use sin and cos to map the range to [-1, 1].
- return vec3(sin(float(v.x)), cos(float(v.y)), sin(float(v.z)));
- }
-
- // Skew factors (non-uniform).
- const half SKEW = 0.3333333; // 1/3
- const half UNSKEW = 0.1666667; // 1/6
-
- // Return range roughly [-1,1].
- // It's because the hash function (that returns a random gradient vector) returns
- // different magnitude of vectors. Noise doesn't have to be in the precise range thus
- // skipped normalize.
- half simplex3d(vec3 p) {
- // Skew the input coordinate, so that we get squashed cubical grid
- vec3 s = floor(p + (p.x + p.y + p.z) * SKEW);
-
- // Unskew back
- vec3 u = s - (s.x + s.y + s.z) * UNSKEW;
-
- // Unskewed coordinate that is relative to p, to compute the noise contribution
- // based on the distance.
- vec3 c0 = p - u;
-
- // We have six simplices (in this case tetrahedron, since we are in 3D) that we
- // could possibly in.
- // Here, we are finding the correct tetrahedron (simplex shape), and traverse its
- // four vertices (c0..3) when computing noise contribution.
- // The way we find them is by comparing c0's x,y,z values.
- // For example in 2D, we can find the triangle (simplex shape in 2D) that we are in
- // by comparing x and y values. i.e. x>y lower, xy0>z0: (1,0,0), (1,1,0), (1,1,1)
- // x0>z0>y0: (1,0,0), (1,0,1), (1,1,1)
- // z0>x0>y0: (0,0,1), (1,0,1), (1,1,1)
- // z0>y0>x0: (0,0,1), (0,1,1), (1,1,1)
- // y0>z0>x0: (0,1,0), (0,1,1), (1,1,1)
- // y0>x0>z0: (0,1,0), (1,1,0), (1,1,1)
- //
- // The rule is:
- // * For offset1, set 1 at the max component, otherwise 0.
- // * For offset2, set 0 at the min component, otherwise 1.
- // * For offset3, set 1 for all.
- //
- // Encode x0-y0, y0-z0, z0-x0 in a vec3
- vec3 en = c0 - c0.yzx;
- // Each represents whether x0>y0, y0>z0, z0>x0
- en = step(vec3(0.), en);
- // en.zxy encodes z0>x0, x0>y0, y0>x0
- vec3 offset1 = en * (1. - en.zxy); // find max
- vec3 offset2 = 1. - en.zxy * (1. - en); // 1-(find min)
- vec3 offset3 = vec3(1.);
-
- vec3 c1 = c0 - offset1 + UNSKEW;
- vec3 c2 = c0 - offset2 + UNSKEW * 2.;
- vec3 c3 = c0 - offset3 + UNSKEW * 3.;
-
- // Kernel summation: dot(max(0, r^2-d^2))^4, noise contribution)
- //
- // First compute d^2, squared distance to the point.
- vec4 w; // w = max(0, r^2 - d^2))
- w.x = dot(c0, c0);
- w.y = dot(c1, c1);
- w.z = dot(c2, c2);
- w.w = dot(c3, c3);
-
- // Noise contribution should decay to zero before they cross the simplex boundary.
- // Usually r^2 is 0.5 or 0.6;
- // 0.5 ensures continuity but 0.6 increases the visual quality for the application
- // where discontinuity isn't noticeable.
- w = max(0.6 - w, 0.);
-
- // Noise contribution from each point.
- vec4 nc;
- nc.x = dot(hash(s), c0);
- nc.y = dot(hash(s + offset1), c1);
- nc.z = dot(hash(s + offset2), c2);
- nc.w = dot(hash(s + offset3), c3);
-
- nc *= w*w*w*w;
-
- // Add all the noise contributions.
- // Should multiply by the possible max contribution to adjust the range in [-1,1].
- return dot(vec4(32.), nc);
- }
-
- // Random rotations.
- // The way you create fractal noise is layering simplex noise with some rotation.
- // To make random cloud looking noise, the rotations should not align. (Otherwise it
- // creates patterned noise).
- // Below rotations only rotate in one axis.
- const mat3 rot1 = mat3(1.0, 0. ,0., 0., 0.15, -0.98, 0., 0.98, 0.15);
- const mat3 rot2 = mat3(-0.95, 0. ,-0.3, 0., 1., 0., 0.3, 0., -0.95);
- const mat3 rot3 = mat3(1.0, 0. ,0., 0., -0.44, -0.89, 0., 0.89, -0.44);
-
- // Octave = 4
- // Divide each coefficient by 3 to produce more grainy noise.
- half simplex3d_fractal(vec3 p) {
- return 0.675 * simplex3d(p * rot1) + 0.225 * simplex3d(2.0 * p * rot2)
- + 0.075 * simplex3d(4.0 * p * rot3) + 0.025 * simplex3d(8.0 * p);
- }
-
- // Screen blend
- vec3 screen(vec3 dest, vec3 src) {
- return dest + src - dest * src;
- }
- """
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
deleted file mode 100644
index ba8f1ace02..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.turbulencenoise
-
-import android.graphics.Color
-import java.util.Random
-
-/** Turbulence noise animation configuration. */
-data class TurbulenceNoiseAnimationConfig(
- /** The number of grids that is used to generate noise. */
- val gridCount: Float = DEFAULT_NOISE_GRID_COUNT,
-
- /** Multiplier for the noise luma matte. Increase this for brighter effects. */
- val luminosityMultiplier: Float = DEFAULT_LUMINOSITY_MULTIPLIER,
-
- /** Initial noise offsets. */
- val noiseOffsetX: Float = random.nextFloat(),
- val noiseOffsetY: Float = random.nextFloat(),
- val noiseOffsetZ: Float = random.nextFloat(),
-
- /**
- * Noise move speed variables.
- *
- * Its sign determines the direction; magnitude determines the speed.
- *
- * ```
- * - [noiseMoveSpeedX] positive: right to left; negative: left to right.
- *
- [noiseMoveSpeedY] positive: bottom to top; negative: top to bottom.
- *
- [noiseMoveSpeedZ] its sign doesn't matter much, as it moves in Z direction. Use it
- * to add turbulence in place.
- * ```
- *
- *
- */
- val noiseMoveSpeedX: Float = 0f,
- val noiseMoveSpeedY: Float = 0f,
- val noiseMoveSpeedZ: Float = DEFAULT_NOISE_SPEED_Z,
-
- /** Color of the effect. */
- val color: Int = DEFAULT_COLOR,
- /** Background color of the effect. */
- val screenColor: Int = DEFAULT_SCREEN_COLOR,
- val width: Float = 0f,
- val height: Float = 0f,
- val maxDuration: Float = DEFAULT_MAX_DURATION_IN_MILLIS,
- val easeInDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS,
- val easeOutDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS,
- val pixelDensity: Float = 1f,
- /**
- * Variants in noise. Higher number means more contrast; lower number means less contrast but
- * make the noise dimmed. You may want to increase the [lumaMatteBlendFactor] to compensate.
- * Expected range [0, 1].
- */
- val lumaMatteBlendFactor: Float = DEFAULT_LUMA_MATTE_BLEND_FACTOR,
- /**
- * Offset for the overall brightness in noise. Higher number makes the noise brighter. You may
- * want to use this if you have made the noise softer using [lumaMatteBlendFactor]. Expected
- * range [0, 1].
- */
- val lumaMatteOverallBrightness: Float = DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS,
- /** Whether to flip the luma mask. */
- val shouldInverseNoiseLuminosity: Boolean = false,
-) {
- companion object {
- const val DEFAULT_MAX_DURATION_IN_MILLIS = 30_000f // Max 30 sec
- const val DEFAULT_EASING_DURATION_IN_MILLIS = 750f
- const val DEFAULT_LUMINOSITY_MULTIPLIER = 1f
- const val DEFAULT_NOISE_GRID_COUNT = 1.2f
- const val DEFAULT_NOISE_SPEED_Z = 0.3f
- const val DEFAULT_COLOR = Color.WHITE
- const val DEFAULT_LUMA_MATTE_BLEND_FACTOR = 1f
- const val DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS = 0f
- const val DEFAULT_SCREEN_COLOR = Color.BLACK
- private val random = Random()
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt
deleted file mode 100644
index e862f0c43a..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.turbulencenoise
-
-import android.view.View
-import androidx.annotation.VisibleForTesting
-
-/** Plays [TurbulenceNoiseView] in ease-in, main (no easing), and ease-out order. */
-class TurbulenceNoiseController(private val turbulenceNoiseView: TurbulenceNoiseView) {
-
- companion object {
- /**
- * States of the turbulence noise animation.
- *
- * The state is designed to be follow the order below: [AnimationState.EASE_IN],
- * [AnimationState.MAIN], [AnimationState.EASE_OUT].
- */
- enum class AnimationState {
- EASE_IN,
- MAIN,
- EASE_OUT,
- NOT_PLAYING
- }
- }
-
- /** Current state of the animation. */
- @VisibleForTesting
- var state: AnimationState = AnimationState.NOT_PLAYING
- set(value) {
- field = value
- if (state == AnimationState.NOT_PLAYING) {
- turbulenceNoiseView.visibility = View.INVISIBLE
- turbulenceNoiseView.clearConfig()
- } else {
- turbulenceNoiseView.visibility = View.VISIBLE
- }
- }
-
- init {
- turbulenceNoiseView.visibility = View.INVISIBLE
- }
-
- /** Updates the color of the noise. */
- fun updateNoiseColor(color: Int) {
- if (state == AnimationState.NOT_PLAYING) {
- return
- }
- turbulenceNoiseView.updateColor(color)
- }
-
- /**
- * Plays [TurbulenceNoiseView] with the given config.
- *
- *
It plays ease-in, main, and ease-out animations in sequence.
- */
- fun play(
- baseType: TurbulenceNoiseShader.Companion.Type,
- config: TurbulenceNoiseAnimationConfig
- ) {
- if (state != AnimationState.NOT_PLAYING) {
- return // Ignore if any of the animation is playing.
- }
-
- turbulenceNoiseView.initShader(baseType, config)
- playEaseInAnimation()
- }
-
- // TODO(b/237282226): Support force finish.
- /** Finishes the main animation, which triggers the ease-out animation. */
- fun finish() {
- if (state == AnimationState.MAIN) {
- turbulenceNoiseView.finish(nextAnimation = this::playEaseOutAnimation)
- }
- }
-
- private fun playEaseInAnimation() {
- if (state != AnimationState.NOT_PLAYING) {
- return
- }
- state = AnimationState.EASE_IN
-
- turbulenceNoiseView.playEaseIn(this::playMainAnimation)
- }
-
- private fun playMainAnimation() {
- if (state != AnimationState.EASE_IN) {
- return
- }
- state = AnimationState.MAIN
-
- turbulenceNoiseView.play(this::playEaseOutAnimation)
- }
-
- private fun playEaseOutAnimation() {
- if (state != AnimationState.MAIN) {
- return
- }
- state = AnimationState.EASE_OUT
-
- turbulenceNoiseView.playEaseOut(onAnimationEnd = { state = AnimationState.NOT_PLAYING })
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
deleted file mode 100644
index 025c8b9dce..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.turbulencenoise
-
-import android.graphics.RuntimeShader
-import com.android.systemui.surfaceeffects.shaders.SolidColorShader
-import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
-import java.lang.Float.max
-
-/**
- * Shader that renders turbulence simplex noise, by default no octave.
- *
- * @param baseType the base [Type] of the shader.
- */
-class TurbulenceNoiseShader(val baseType: Type = Type.SIMPLEX_NOISE) :
- RuntimeShader(getShader(baseType)) {
- // language=AGSL
- companion object {
- /** Uniform name for the background buffer (e.g. image, solid color, etc.). */
- const val BACKGROUND_UNIFORM = "in_src"
- private const val UNIFORMS =
- """
- uniform shader ${BACKGROUND_UNIFORM};
- uniform float in_gridNum;
- uniform vec3 in_noiseMove;
- uniform vec2 in_size;
- uniform float in_aspectRatio;
- uniform float in_opacity;
- uniform float in_pixelDensity;
- uniform float in_inverseLuma;
- uniform half in_lumaMatteBlendFactor;
- uniform half in_lumaMatteOverallBrightness;
- layout(color) uniform vec4 in_color;
- layout(color) uniform vec4 in_screenColor;
- """
-
- private const val SIMPLEX_SHADER =
- """
- vec4 main(vec2 p) {
- vec2 uv = p / in_size.xy;
- uv.x *= in_aspectRatio;
-
- // Compute turbulence effect with the uv distorted with simplex noise.
- vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum;
- vec3 color = getColorTurbulenceMask(simplex3d(noiseP) * in_inverseLuma);
-
- // Blend the result with the background color.
- color = in_src.eval(p).rgb + color * 0.6;
-
- // Add dither with triangle distribution to avoid color banding. Dither in the
- // shader here as we are in gamma space.
- float dither = triangleNoise(p * in_pixelDensity) / 255.;
- color += dither.rrr;
-
- // Return the pre-multiplied alpha result, i.e. [R*A, G*A, B*A, A].
- return vec4(color * in_opacity, in_opacity);
- }
- """
-
- private const val FRACTAL_SHADER =
- """
- vec4 main(vec2 p) {
- vec2 uv = p / in_size.xy;
- uv.x *= in_aspectRatio;
-
- vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum;
- vec3 color = getColorTurbulenceMask(simplex3d_fractal(noiseP) * in_inverseLuma);
-
- // Blend the result with the background color.
- color = in_src.eval(p).rgb + color * 0.6;
-
- // Skip dithering.
- return vec4(color * in_opacity, in_opacity);
- }
- """
-
- /**
- * This effect has two layers: color turbulence effect with sparkles on top.
- * 1. Gets the luma matte using Simplex noise.
- * 2. Generate a colored turbulence layer with the luma matte.
- * 3. Generate a colored sparkle layer with the same luma matter.
- * 4. Apply a screen color to the background image.
- * 5. Composite the previous result with the color turbulence.
- * 6. Composite the latest result with the sparkles.
- */
- private const val SIMPLEX_SPARKLE_SHADER =
- """
- vec4 main(vec2 p) {
- vec2 uv = p / in_size.xy;
- uv.x *= in_aspectRatio;
-
- vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum;
- // Luma is used for both color and sparkle masks.
- float luma = simplex3d(noiseP) * in_inverseLuma;
-
- // Get color layer (color mask with in_color applied)
- vec3 colorLayer = getColorTurbulenceMask(simplex3d(noiseP) * in_inverseLuma);
- float dither = triangleNoise(p * in_pixelDensity) / 255.;
- colorLayer += dither.rrr;
-
- // Get sparkle layer (sparkle mask with particles & in_color applied)
- vec3 sparkleLayer = getSparkleTurbulenceMask(luma, p);
-
- // Composite with the background.
- half4 bgColor = in_src.eval(p);
- half sparkleOpacity = smoothstep(0, 0.75, in_opacity);
-
- half3 effect = screen(bgColor.rgb, in_screenColor.rgb);
- effect = screen(effect, colorLayer * 0.22);
- effect += sparkleLayer * sparkleOpacity;
-
- return mix(bgColor, vec4(effect, 1.), in_opacity);
- }
- """
-
- private const val COMMON_FUNCTIONS =
- /**
- * Below two functions generate turbulence layers (color or sparkles applied) with the
- * given luma matte. They both return a mask with in_color applied.
- */
- """
- vec3 getColorTurbulenceMask(float luma) {
- // Bring it to [0, 1] range.
- luma = luma * 0.5 + 0.5;
-
- half colorLuma =
- saturate(luma * in_lumaMatteBlendFactor + in_lumaMatteOverallBrightness)
- * in_opacity;
- vec3 colorLayer = maskLuminosity(in_color.rgb, colorLuma);
-
- return colorLayer;
- }
-
- vec3 getSparkleTurbulenceMask(float luma, vec2 p) {
- half lumaIntensity = 1.75;
- half lumaBrightness = -1.3;
- half sparkleLuma = max(luma * lumaIntensity + lumaBrightness, 0.);
-
- float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_noiseMove.z);
- vec3 sparkleLayer = maskLuminosity(in_color.rgb * sparkle, sparkleLuma);
-
- return sparkleLayer;
- }
- """
- private const val SIMPLEX_NOISE_SHADER =
- ShaderUtilLibrary.SHADER_LIB + UNIFORMS + COMMON_FUNCTIONS + SIMPLEX_SHADER
- private const val FRACTAL_NOISE_SHADER =
- ShaderUtilLibrary.SHADER_LIB + UNIFORMS + COMMON_FUNCTIONS + FRACTAL_SHADER
- private const val SPARKLE_NOISE_SHADER =
- ShaderUtilLibrary.SHADER_LIB + UNIFORMS + COMMON_FUNCTIONS + SIMPLEX_SPARKLE_SHADER
-
- enum class Type {
- /** Effect with a simple color noise turbulence. */
- SIMPLEX_NOISE,
- /** Effect with a simple color noise turbulence, with fractal. */
- SIMPLEX_NOISE_FRACTAL,
- /** Effect with color & sparkle turbulence with screen color layer. */
- SIMPLEX_NOISE_SPARKLE
- }
-
- fun getShader(type: Type): String {
- return when (type) {
- Type.SIMPLEX_NOISE -> SIMPLEX_NOISE_SHADER
- Type.SIMPLEX_NOISE_FRACTAL -> FRACTAL_NOISE_SHADER
- Type.SIMPLEX_NOISE_SPARKLE -> SPARKLE_NOISE_SHADER
- }
- }
- }
-
- /** Convenient way for updating multiple uniform values via config object. */
- fun applyConfig(config: TurbulenceNoiseAnimationConfig) {
- setGridCount(config.gridCount)
- setPixelDensity(config.pixelDensity)
- setColor(config.color)
- setScreenColor(config.screenColor)
- setSize(config.width, config.height)
- setLumaMatteFactors(config.lumaMatteBlendFactor, config.lumaMatteOverallBrightness)
- setInverseNoiseLuminosity(config.shouldInverseNoiseLuminosity)
- setNoiseMove(config.noiseOffsetX, config.noiseOffsetY, config.noiseOffsetZ)
- }
-
- /** Sets the number of grid for generating noise. */
- fun setGridCount(gridNumber: Float = 1.0f) {
- setFloatUniform("in_gridNum", gridNumber)
- }
-
- /**
- * Sets the pixel density of the screen.
- *
- * Used it for noise dithering.
- */
- fun setPixelDensity(pixelDensity: Float) {
- setFloatUniform("in_pixelDensity", pixelDensity)
- }
-
- /** Sets the noise color of the effect. Alpha is ignored. */
- fun setColor(color: Int) {
- setColorUniform("in_color", color)
- }
-
- /**
- * Sets the color that is used for blending on top of the background color/image. Only relevant
- * to [Type.SIMPLEX_NOISE_SPARKLE].
- */
- fun setScreenColor(color: Int) {
- setColorUniform("in_screenColor", color)
- }
-
- /**
- * Sets the background color of the effect. Alpha is ignored. If you are using [RenderEffect],
- * no need to call this function since the background image of the View will be used.
- */
- fun setBackgroundColor(color: Int) {
- setInputShader(BACKGROUND_UNIFORM, SolidColorShader(color))
- }
-
- /**
- * Sets the opacity of the effect. Not intended to set by the client as it is used for
- * ease-in/out animations.
- *
- * Expected value range is [1, 0].
- */
- fun setOpacity(opacity: Float) {
- setFloatUniform("in_opacity", opacity)
- }
-
- /** Sets the size of the shader. */
- fun setSize(width: Float, height: Float) {
- setFloatUniform("in_size", width, height)
- setFloatUniform("in_aspectRatio", width / max(height, 0.001f))
- }
-
- /**
- * Sets blend and brightness factors of the luma matte.
- *
- * @param lumaMatteBlendFactor increases or decreases the amount of variance in noise. Setting
- * this a lower number removes variations. I.e. the turbulence noise will look more blended.
- * Expected input range is [0, 1].
- * @param lumaMatteOverallBrightness adds the overall brightness of the turbulence noise.
- * Expected input range is [0, 1].
- *
- * Example usage: You may want to apply a small number to [lumaMatteBlendFactor], such as 0.2,
- * which makes the noise look softer. However it makes the overall noise look dim, so you want
- * offset something like 0.3 for [lumaMatteOverallBrightness] to bring back its overall
- * brightness.
- */
- fun setLumaMatteFactors(
- lumaMatteBlendFactor: Float = 1f,
- lumaMatteOverallBrightness: Float = 0f
- ) {
- setFloatUniform("in_lumaMatteBlendFactor", lumaMatteBlendFactor)
- setFloatUniform("in_lumaMatteOverallBrightness", lumaMatteOverallBrightness)
- }
-
- /**
- * Sets whether to inverse the luminosity of the noise.
- *
- * By default noise will be used as a luma matte as is. This means that you will see color in
- * the brighter area. If you want to invert it, meaning blend color onto the darker side, set to
- * true.
- */
- fun setInverseNoiseLuminosity(inverse: Boolean) {
- setFloatUniform("in_inverseLuma", if (inverse) -1f else 1f)
- }
-
- /** Current noise movements in x, y, and z axes. */
- var noiseOffsetX: Float = 0f
- private set
- var noiseOffsetY: Float = 0f
- private set
- var noiseOffsetZ: Float = 0f
- private set
-
- /** Sets noise move offset in x, y, and z direction. */
- fun setNoiseMove(x: Float, y: Float, z: Float) {
- noiseOffsetX = x
- noiseOffsetY = y
- noiseOffsetZ = z
- setFloatUniform("in_noiseMove", noiseOffsetX, noiseOffsetY, noiseOffsetZ)
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt
deleted file mode 100644
index 5e72e3bd1e..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.surfaceeffects.turbulencenoise
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.ValueAnimator
-import android.content.Context
-import android.graphics.BlendMode
-import android.graphics.Canvas
-import android.graphics.Paint
-import android.util.AttributeSet
-import android.view.View
-import androidx.annotation.VisibleForTesting
-
-/**
- * View that renders turbulence noise effect.
- *
- *
Use [TurbulenceNoiseController] to control the turbulence animation. If you want to make some
- * other turbulence noise effects, either add functionality to [TurbulenceNoiseController] or create
- * another controller instead of extend or modify the [TurbulenceNoiseView].
- *
- *
Please keep the [TurbulenceNoiseView] (or View in general) not aware of the state.
- *
- *
Please avoid inheriting the View if possible. Instead, reconsider adding a controller for a
- * new case.
- */
-class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
-
- companion object {
- private const val MS_TO_SEC = 0.001f
- }
-
- private val paint = Paint()
- @VisibleForTesting var turbulenceNoiseShader: TurbulenceNoiseShader? = null
- @VisibleForTesting var noiseConfig: TurbulenceNoiseAnimationConfig? = null
- @VisibleForTesting var currentAnimator: ValueAnimator? = null
-
- override fun onDraw(canvas: Canvas) {
- if (!canvas.isHardwareAccelerated) {
- // Drawing with the turbulence noise shader requires hardware acceleration, so skip
- // if it's unsupported.
- return
- }
-
- canvas.drawPaint(paint)
- }
-
- /** Updates the color during the animation. No-op if there's no animation playing. */
- internal fun updateColor(color: Int) {
- turbulenceNoiseShader?.setColor(color)
- }
-
- /** Plays the turbulence noise with no easing. */
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- fun play(onAnimationEnd: Runnable? = null) {
- if (noiseConfig == null) {
- return
- }
- val config = noiseConfig!!
- val shader = turbulenceNoiseShader!!
-
- val animator = ValueAnimator.ofFloat(0f, 1f)
- animator.duration = config.maxDuration.toLong()
-
- // Animation should start from the initial position to avoid abrupt transition.
- val initialX = shader.noiseOffsetX
- val initialY = shader.noiseOffsetY
- val initialZ = shader.noiseOffsetZ
-
- animator.addUpdateListener { updateListener ->
- val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
- shader.setNoiseMove(
- initialX + timeInSec * config.noiseMoveSpeedX,
- initialY + timeInSec * config.noiseMoveSpeedY,
- initialZ + timeInSec * config.noiseMoveSpeedZ
- )
-
- shader.setOpacity(config.luminosityMultiplier)
-
- invalidate()
- }
-
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- currentAnimator = null
- onAnimationEnd?.run()
- }
- }
- )
-
- animator.start()
- currentAnimator = animator
- }
-
- /** Plays the turbulence noise with linear ease-in. */
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- fun playEaseIn(onAnimationEnd: Runnable? = null) {
- if (noiseConfig == null) {
- return
- }
- val config = noiseConfig!!
- val shader = turbulenceNoiseShader!!
-
- val animator = ValueAnimator.ofFloat(0f, 1f)
- animator.duration = config.easeInDuration.toLong()
-
- // Animation should start from the initial position to avoid abrupt transition.
- val initialX = shader.noiseOffsetX
- val initialY = shader.noiseOffsetY
- val initialZ = shader.noiseOffsetZ
-
- animator.addUpdateListener { updateListener ->
- val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
- val progress = updateListener.animatedValue as Float
-
- shader.setNoiseMove(
- initialX + timeInSec * config.noiseMoveSpeedX,
- initialY + timeInSec * config.noiseMoveSpeedY,
- initialZ + timeInSec * config.noiseMoveSpeedZ
- )
-
- // TODO: Replace it with a better curve.
- shader.setOpacity(progress * config.luminosityMultiplier)
-
- invalidate()
- }
-
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- currentAnimator = null
- onAnimationEnd?.run()
- }
- }
- )
-
- animator.start()
- currentAnimator = animator
- }
-
- /** Plays the turbulence noise with linear ease-out. */
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- fun playEaseOut(onAnimationEnd: Runnable? = null) {
- if (noiseConfig == null) {
- return
- }
- val config = noiseConfig!!
- val shader = turbulenceNoiseShader!!
-
- val animator = ValueAnimator.ofFloat(0f, 1f)
- animator.duration = config.easeOutDuration.toLong()
-
- // Animation should start from the initial position to avoid abrupt transition.
- val initialX = shader.noiseOffsetX
- val initialY = shader.noiseOffsetY
- val initialZ = shader.noiseOffsetZ
-
- animator.addUpdateListener { updateListener ->
- val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
- val progress = updateListener.animatedValue as Float
-
- shader.setNoiseMove(
- initialX + timeInSec * config.noiseMoveSpeedX,
- initialY + timeInSec * config.noiseMoveSpeedY,
- initialZ + timeInSec * config.noiseMoveSpeedZ
- )
-
- // TODO: Replace it with a better curve.
- shader.setOpacity((1f - progress) * config.luminosityMultiplier)
-
- invalidate()
- }
-
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- currentAnimator = null
- onAnimationEnd?.run()
- }
- }
- )
-
- animator.start()
- currentAnimator = animator
- }
-
- /** Finishes the current animation if playing and plays the next animation if given. */
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- fun finish(nextAnimation: Runnable? = null) {
- // Calling Animator#end sets the animation state back to the initial state. Using pause to
- // avoid visual artifacts.
- currentAnimator?.pause()
- currentAnimator = null
-
- nextAnimation?.run()
- }
-
- /** Applies shader uniforms. Must be called before playing animation. */
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- fun initShader(
- baseType: TurbulenceNoiseShader.Companion.Type,
- config: TurbulenceNoiseAnimationConfig
- ) {
- noiseConfig = config
- if (turbulenceNoiseShader == null || turbulenceNoiseShader?.baseType != baseType) {
- turbulenceNoiseShader = TurbulenceNoiseShader(baseType)
-
- paint.shader = turbulenceNoiseShader!!
- }
- turbulenceNoiseShader!!.applyConfig(config)
- }
-
- /** Sets the blend mode of the View. */
- fun setBlendMode(blendMode: BlendMode) {
- paint.blendMode = blendMode
- }
-
- internal fun clearConfig() {
- noiseConfig = null
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt b/systemUIAnim/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt
deleted file mode 100644
index 7ed3b87f68..0000000000
--- a/systemUIAnim/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.utils
-
-/** Copied from android.utils.MathUtils */
-object MathUtils {
- fun lerp(start: Float, stop: Float, amount: Float): Float {
- return start + (stop - start) * amount
- }
-}
diff --git a/systemUIAnim/src/com/android/systemui/util/AnimatorExtensions.kt b/systemUIAnim/src/com/android/systemui/util/AnimatorExtensions.kt
deleted file mode 100644
index 35dbb89ad8..0000000000
--- a/systemUIAnim/src/com/android/systemui/util/AnimatorExtensions.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.util
-
-import androidx.core.animation.Animator
-
-/**
- * Add an action which will be invoked when the animation has ended.
- *
- * @return the [Animator.AnimatorListener] added to the Animator
- * @see Animator.end
- */
-inline fun Animator.doOnEnd(
- crossinline action: (animator: Animator) -> Unit
-): Animator.AnimatorListener = addListener(onEnd = action)
-
-/**
- * Add an action which will be invoked when the animation has started.
- *
- * @return the [Animator.AnimatorListener] added to the Animator
- * @see Animator.start
- */
-inline fun Animator.doOnStart(
- crossinline action: (animator: Animator) -> Unit
-): Animator.AnimatorListener = addListener(onStart = action)
-
-/**
- * Add an action which will be invoked when the animation has been cancelled.
- *
- * @return the [Animator.AnimatorListener] added to the Animator
- * @see Animator.cancel
- */
-inline fun Animator.doOnCancel(
- crossinline action: (animator: Animator) -> Unit
-): Animator.AnimatorListener = addListener(onCancel = action)
-
-/**
- * Add an action which will be invoked when the animation has repeated.
- *
- * @return the [Animator.AnimatorListener] added to the Animator
- */
-inline fun Animator.doOnRepeat(
- crossinline action: (animator: Animator) -> Unit
-): Animator.AnimatorListener = addListener(onRepeat = action)
-
-/**
- * Add a listener to this Animator using the provided actions.
- *
- * @return the [Animator.AnimatorListener] added to the Animator
- */
-inline fun Animator.addListener(
- crossinline onEnd: (animator: Animator) -> Unit = {},
- crossinline onStart: (animator: Animator) -> Unit = {},
- crossinline onCancel: (animator: Animator) -> Unit = {},
- crossinline onRepeat: (animator: Animator) -> Unit = {}
-): Animator.AnimatorListener {
- val listener =
- object : Animator.AnimatorListener {
- override fun onAnimationRepeat(animator: Animator) = onRepeat(animator)
- override fun onAnimationEnd(animator: Animator) = onEnd(animator)
- override fun onAnimationCancel(animator: Animator) = onCancel(animator)
- override fun onAnimationStart(animator: Animator) = onStart(animator)
- }
- addListener(listener)
- return listener
-}
diff --git a/systemUIAnim/src/com/android/systemui/util/Dialog.kt b/systemUIAnim/src/com/android/systemui/util/Dialog.kt
deleted file mode 100644
index 9dd23289d8..0000000000
--- a/systemUIAnim/src/com/android/systemui/util/Dialog.kt
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.util
-
-import android.app.Dialog
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
-import android.widget.FrameLayout
-import android.window.OnBackInvokedDispatcher
-import com.android.systemui.animation.back.BackAnimationSpec
-import com.android.systemui.animation.back.BackTransformation
-import com.android.systemui.animation.back.applyTo
-import com.android.systemui.animation.back.floatingSystemSurfacesForSysUi
-import com.android.systemui.animation.back.onBackAnimationCallbackFrom
-import com.android.systemui.animation.back.registerOnBackInvokedCallbackOnViewAttached
-import com.android.systemui.animation.view.LaunchableFrameLayout
-
-/**
- * Register on the Dialog's [OnBackInvokedDispatcher] an animation using the [BackAnimationSpec].
- * The [BackTransformation] will be applied on the [targetView].
- */
-@JvmOverloads
-fun Dialog.registerAnimationOnBackInvoked(
- targetView: View,
- backAnimationSpec: BackAnimationSpec =
- BackAnimationSpec.floatingSystemSurfacesForSysUi(
- displayMetricsProvider = { targetView.resources.displayMetrics },
- ),
-) {
- targetView.registerOnBackInvokedCallbackOnViewAttached(
- onBackInvokedDispatcher = onBackInvokedDispatcher,
- onBackAnimationCallback =
- onBackAnimationCallbackFrom(
- backAnimationSpec = backAnimationSpec,
- displayMetrics = targetView.resources.displayMetrics,
- onBackProgressed = { backTransformation -> backTransformation.applyTo(targetView) },
- onBackInvoked = { dismiss() },
- ),
- )
-}
-
-/**
- * Make the dialog window (and therefore its DecorView) fullscreen to make it possible to animate
- * outside its bounds. No-op if the dialog is already fullscreen.
- *
- *
Returns null if the dialog is already fullscreen. Otherwise, returns a pair containing a view
- * and a layout listener. The new view matches the original dialog DecorView in size, position, and
- * background. This new view will be a child of the modified, transparent, fullscreen DecorView. The
- * layout listener is listening to changes to the modified DecorView. It is the responsibility of
- * the caller to deregister the listener when the dialog is dismissed.
- */
-fun Dialog.maybeForceFullscreen(): Pair? {
- // Create the dialog so that its onCreate() method is called, which usually sets the dialog
- // content.
- create()
-
- val window = window!!
- val decorView = window.decorView as ViewGroup
-
- val isWindowFullscreen =
- window.attributes.width == MATCH_PARENT && window.attributes.height == MATCH_PARENT
- if (isWindowFullscreen) {
- return null
- }
-
- // We will make the dialog window (and therefore its DecorView) fullscreen to make it possible
- // to animate outside its bounds.
- //
- // Before that, we add a new View as a child of the DecorView with the same size and gravity as
- // that DecorView, then we add all original children of the DecorView to that new View. Finally
- // we remove the background of the DecorView and add it to the new View, then we make the
- // DecorView fullscreen. This new View now acts as a fake (non fullscreen) window.
- //
- // On top of that, we also add a fullscreen transparent background between the DecorView and the
- // view that we added so that we can dismiss the dialog when this view is clicked. This is
- // necessary because DecorView overrides onTouchEvent and therefore we can't set the click
- // listener directly on the (now fullscreen) DecorView.
- val fullscreenTransparentBackground = FrameLayout(context)
- decorView.addView(
- fullscreenTransparentBackground,
- 0 /* index */,
- FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
- )
-
- val dialogContentWithBackground = LaunchableFrameLayout(context)
- dialogContentWithBackground.background = decorView.background
-
- // Make the window background transparent. Note that setting the window (or DecorView)
- // background drawable to null leads to issues with background color (not being transparent) or
- // with insets that are not refreshed. Therefore we need to set it to something not null, hence
- // we are using android.R.color.transparent here.
- window.setBackgroundDrawableResource(android.R.color.transparent)
-
- // Close the dialog when clicking outside of it.
- fullscreenTransparentBackground.setOnClickListener { dismiss() }
- dialogContentWithBackground.isClickable = true
-
- // Make sure the transparent and dialog backgrounds are not focusable by accessibility
- // features.
- fullscreenTransparentBackground.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
- dialogContentWithBackground.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
-
- fullscreenTransparentBackground.addView(
- dialogContentWithBackground,
- FrameLayout.LayoutParams(
- window.attributes.width,
- window.attributes.height,
- window.attributes.gravity
- )
- )
-
- // Move all original children of the DecorView to the new View we just added.
- for (i in 1 until decorView.childCount) {
- val view = decorView.getChildAt(1)
- decorView.removeViewAt(1)
- dialogContentWithBackground.addView(view)
- }
-
- // Make the window fullscreen and add a layout listener to ensure it stays fullscreen.
- window.setLayout(MATCH_PARENT, MATCH_PARENT)
- val decorViewLayoutListener =
- View.OnLayoutChangeListener {
- v,
- left,
- top,
- right,
- bottom,
- oldLeft,
- oldTop,
- oldRight,
- oldBottom ->
- if (
- window.attributes.width != MATCH_PARENT || window.attributes.height != MATCH_PARENT
- ) {
- // The dialog size changed, copy its size to dialogContentWithBackground and make
- // the dialog window full screen again.
- val layoutParams = dialogContentWithBackground.layoutParams
- layoutParams.width = window.attributes.width
- layoutParams.height = window.attributes.height
- dialogContentWithBackground.layoutParams = layoutParams
- window.setLayout(MATCH_PARENT, MATCH_PARENT)
- }
- }
- decorView.addOnLayoutChangeListener(decorViewLayoutListener)
-
- return dialogContentWithBackground to decorViewLayoutListener
-}
diff --git a/systemUIAnim/src/com/android/systemui/util/Dimension.kt b/systemUIAnim/src/com/android/systemui/util/Dimension.kt
deleted file mode 100644
index 4bc9972dd5..0000000000
--- a/systemUIAnim/src/com/android/systemui/util/Dimension.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.util
-
-import android.content.Context
-import android.content.res.Resources
-import android.util.DisplayMetrics
-import android.util.TypedValue
-
-/** Convert [this] number of dps to device pixels. */
-fun Number.dpToPx(context: Context): Float = dpToPx(resources = context.resources)
-
-/** Convert [this] number of dps to device pixels. */
-fun Number.dpToPx(resources: Resources): Float = dpToPx(displayMetrics = resources.displayMetrics)
-
-/** Convert [this] number of dps to device pixels. */
-fun Number.dpToPx(displayMetrics: DisplayMetrics): Float =
- TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, toFloat(), displayMetrics)
diff --git a/systemUICommon/.gitignore b/systemUICommon/.gitignore
deleted file mode 100644
index f9a33dbbcc..0000000000
--- a/systemUICommon/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-.idea/
-.gradle/
-gradle/
-build/
-gradlew*
-local.properties
-*.iml
-android.properties
-buildSrc
\ No newline at end of file
diff --git a/systemUICommon/Android.bp b/systemUICommon/Android.bp
deleted file mode 100644
index 6fc13d7e0d..0000000000
--- a/systemUICommon/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (C) 2023 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_team: "trendy_team_system_ui_please_use_a_more_specific_subteam_if_possible_",
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
-}
-
-android_library {
-
- name: "SystemUICommon",
- use_resource_processor: true,
-
- srcs: [
- "src/**/*.java",
- "src/**/*.kt",
- ],
-
- static_libs: [
- "androidx.core_core-ktx",
- ],
-
- manifest: "AndroidManifest.xml",
- kotlincflags: ["-Xjvm-default=all"],
-}
diff --git a/systemUICommon/AndroidManifest.xml b/systemUICommon/AndroidManifest.xml
deleted file mode 100644
index e07df26b5a..0000000000
--- a/systemUICommon/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/systemUICommon/OWNERS b/systemUICommon/OWNERS
deleted file mode 100644
index 9b8a79e6f3..0000000000
--- a/systemUICommon/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-darrellshi@google.com
-evanlaird@google.com
diff --git a/systemUICommon/README.md b/systemUICommon/README.md
deleted file mode 100644
index 1cc5277aa8..0000000000
--- a/systemUICommon/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# SystemUICommon
-
-`SystemUICommon` is a module within SystemUI that hosts standalone helper libraries. It is intended to be used by other modules, and therefore should not have other SystemUI dependencies to avoid circular dependencies.
-
-To maintain the structure of this module, please refrain from adding components at the top level. Instead, add them to specific sub-packages, such as `systemui/common/buffer/`. This will help to keep the module organized and easy to navigate.
diff --git a/systemUICommon/build.gradle b/systemUICommon/build.gradle
deleted file mode 100644
index 38842570a7..0000000000
--- a/systemUICommon/build.gradle
+++ /dev/null
@@ -1,17 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'org.jetbrains.kotlin.android'
-}
-
-android {
- namespace "com.android.systemui.common"
-
- sourceSets {
- main {
- java.srcDirs = ['src']
- manifest.srcFile 'AndroidManifest.xml'
- }
- }
-}
-
-addFrameworkJar('framework-15.jar')
diff --git a/systemUICommon/src/com/android/systemui/common/buffer/RingBuffer.kt b/systemUICommon/src/com/android/systemui/common/buffer/RingBuffer.kt
deleted file mode 100644
index 4734a3887f..0000000000
--- a/systemUICommon/src/com/android/systemui/common/buffer/RingBuffer.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.common.buffer
-
-import kotlin.math.max
-
-/**
- * A simple ring buffer of recycled items
- *
- * Use [advance] to add items to the buffer.
- *
- * As the buffer is used, it will grow, allocating new instances of T using [factory] until it
- * reaches [maxSize]. After this point, no new instances will be created. Instead, calls to
- * [advance] will recycle the "oldest" instance from the start of the buffer, placing it at the end.
- *
- * The items in the buffer are "recycled" in that they are reused, but it is up to the caller of
- * [advance] to properly reset any data that was previously stored on those items.
- *
- * @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
- * growing to [maxSize].
- */
-class RingBuffer(private val maxSize: Int, private val factory: () -> T) : Iterable {
-
- private val buffer = MutableList(maxSize) { null }
-
- /**
- * An abstract representation that points to the "end" of the buffer, i.e. one beyond the
- * location of the last item. Increments every time [advance] is called and is never wrapped.
- *
- * Use [indexOf] to calculate the associated index into the backing array. Before the buffer has
- * been completely filled, this will point to the next empty slot to fill; afterwards it will
- * point to the next item that should be recycled (which, because the buffer is a ring, is the
- * "start" of the buffer).
- *
- * This value is unlikely to overflow. Assuming [advance] is called at rate of 100 calls/ms,
- * omega will overflow after a little under three million years of continuous operation.
- */
- private var omega: Long = 0
-
- /**
- * The number of items currently stored in the buffer. Calls to [advance] will cause this value
- * to increase by one until it reaches [maxSize].
- */
- val size: Int
- get() = if (omega < maxSize) omega.toInt() else maxSize
-
- /**
- * Adds an item to the end of the buffer. The caller should reset the returned item's contents
- * and then fill it with appropriate data.
- *
- * If the buffer is not yet full, uses [factory] to create a new item. Otherwise, it recycles
- * the oldest item from the front of the buffer and moves it to the end.
- *
- * Importantly, recycled items are returned as-is, without being reset. They will retain any
- * data that was previously stored on them. Callers must make sure to clear any historical data,
- * if necessary.
- */
- fun advance(): T {
- val index = indexOf(omega)
- omega += 1
- val entry = buffer[index] ?: factory().also { buffer[index] = it }
- return entry
- }
-
- /**
- * Returns the value stored at [index], which can range from 0 (the "start", or oldest element
- * of the buffer) to [size] - 1 (the "end", or newest element of the buffer).
- */
- operator fun get(index: Int): T {
- if (index < 0 || index >= size) {
- throw IndexOutOfBoundsException("Index $index is out of bounds")
- }
-
- // If omega is larger than the maxSize, then the buffer is full, and omega is equivalent
- // to the "start" of the buffer. If omega is smaller than the maxSize, then the buffer is
- // not yet full and our start should be 0. However, in modspace, maxSize and 0 are
- // equivalent, so we can get away with using it as the start value instead.
- val start = max(omega, maxSize.toLong())
-
- return buffer[indexOf(start + index)]!!
- }
-
- override fun iterator(): Iterator {
- return object : Iterator {
- private var position: Int = 0
-
- override fun next(): T {
- if (position >= size) {
- throw NoSuchElementException()
- }
- return get(position).also { position += 1 }
- }
-
- override fun hasNext(): Boolean {
- return position < size
- }
- }
- }
-
- private fun indexOf(position: Long): Int {
- return (position % maxSize).toInt()
- }
-}
diff --git a/systemUILog/.gitignore b/systemUILog/.gitignore
deleted file mode 100644
index f9a33dbbcc..0000000000
--- a/systemUILog/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-.idea/
-.gradle/
-gradle/
-build/
-gradlew*
-local.properties
-*.iml
-android.properties
-buildSrc
\ No newline at end of file
diff --git a/systemUILog/Android.bp b/systemUILog/Android.bp
deleted file mode 100644
index 627ac4b7c3..0000000000
--- a/systemUILog/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2023 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
-}
-
-android_library {
- name: "SystemUILogLib",
- srcs: [
- "src/**/*.java",
- "src/**/*.kt",
- ],
- static_libs: [
- "androidx.core_core-ktx",
- "androidx.annotation_annotation",
- "error_prone_annotations",
- "SystemUICommon",
- ],
- manifest: "AndroidManifest.xml",
- kotlincflags: ["-Xjvm-default=all"],
-}
diff --git a/systemUILog/AndroidManifest.xml b/systemUILog/AndroidManifest.xml
deleted file mode 100644
index 4021e1a5f7..0000000000
--- a/systemUILog/AndroidManifest.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
diff --git a/systemUILog/build.gradle b/systemUILog/build.gradle
deleted file mode 100644
index c1c63a67bb..0000000000
--- a/systemUILog/build.gradle
+++ /dev/null
@@ -1,27 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'org.jetbrains.kotlin.android'
-}
-
-android {
- namespace "com.android.systemui.log"
- buildFeatures {
- aidl true
- }
- sourceSets {
- main {
- java.srcDirs = ['src']
- aidl.srcDirs = ['src']
- manifest.srcFile 'AndroidManifest.xml'
- }
- }
-}
-
-addFrameworkJar('framework-15.jar')
-compileOnlyCommonJars()
-
-dependencies {
- compileOnly projects.systemUIPluginCore
- compileOnly projects.systemUICommon
- implementation 'com.google.errorprone:error_prone_annotations:2.33.0'
-}
diff --git a/systemUILog/src/com/android/systemui/log/ConstantStringsLogger.kt b/systemUILog/src/com/android/systemui/log/ConstantStringsLogger.kt
deleted file mode 100644
index bc35095a34..0000000000
--- a/systemUILog/src/com/android/systemui/log/ConstantStringsLogger.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log
-
-import com.google.errorprone.annotations.CompileTimeConstant
-
-/**
- * Handy for adding basic logging with CompileTimeConstant strings - so logging with no variables.
- * Most likely you want to delegate it to [ConstantStringsLoggerImpl].
- */
-interface ConstantStringsLogger {
- fun v(@CompileTimeConstant msg: String)
-
- fun d(@CompileTimeConstant msg: String)
-
- fun w(@CompileTimeConstant msg: String)
-
- fun e(@CompileTimeConstant msg: String)
-}
diff --git a/systemUILog/src/com/android/systemui/log/ConstantStringsLoggerImpl.kt b/systemUILog/src/com/android/systemui/log/ConstantStringsLoggerImpl.kt
deleted file mode 100644
index a4f4e13473..0000000000
--- a/systemUILog/src/com/android/systemui/log/ConstantStringsLoggerImpl.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log
-
-import com.android.systemui.log.core.LogLevel
-import com.google.errorprone.annotations.CompileTimeConstant
-
-class ConstantStringsLoggerImpl(val buffer: LogBuffer, val tag: String) : ConstantStringsLogger {
- override fun v(@CompileTimeConstant msg: String) = buffer.log(tag, LogLevel.VERBOSE, msg)
-
- override fun d(@CompileTimeConstant msg: String) = buffer.log(tag, LogLevel.DEBUG, msg)
-
- override fun w(@CompileTimeConstant msg: String) = buffer.log(tag, LogLevel.WARNING, msg)
-
- override fun e(@CompileTimeConstant msg: String) = buffer.log(tag, LogLevel.ERROR, msg)
-}
diff --git a/systemUILog/src/com/android/systemui/log/LogBuffer.kt b/systemUILog/src/com/android/systemui/log/LogBuffer.kt
deleted file mode 100644
index e0051f5946..0000000000
--- a/systemUILog/src/com/android/systemui/log/LogBuffer.kt
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log
-
-import android.os.Trace
-import android.util.Log
-import com.android.systemui.common.buffer.RingBuffer
-import com.android.systemui.log.core.LogLevel
-import com.android.systemui.log.core.LogMessage
-import com.android.systemui.log.core.MessageBuffer
-import com.android.systemui.log.core.MessageInitializer
-import com.android.systemui.log.core.MessagePrinter
-import com.google.errorprone.annotations.CompileTimeConstant
-import java.io.PrintWriter
-import java.util.concurrent.ArrayBlockingQueue
-import java.util.concurrent.BlockingQueue
-import kotlin.concurrent.thread
-import kotlin.math.max
-
-/**
- * A simple ring buffer of recyclable log messages
- *
- * The goal of this class is to enable logging that is both extremely chatty and extremely
- * lightweight. If done properly, logging a message will not result in any heap allocations or
- * string generation. Messages are only converted to strings if the log is actually dumped (usually
- * as the result of taking a bug report).
- *
- * You can dump the entire buffer at any time by running:
- * ```
- * $ adb shell dumpsys activity service com.android.systemui/.SystemUIService
- * ```
- *
- * ...where `bufferName` is the (case-sensitive) [name] passed to the constructor.
- *
- * By default, only messages of WARN level or higher are echoed to logcat, but this can be adjusted
- * locally (usually for debugging purposes).
- *
- * To enable logcat echoing for an entire buffer:
- * ```
- * $ adb shell settings put global systemui/buffer/
- * ```
- *
- * To enable logcat echoing for a specific tag:
- * ```
- * $ adb shell settings put global systemui/tag/
- * ```
- *
- * In either case, `level` can be any of `verbose`, `debug`, `info`, `warn`, `error`, `assert`, or
- * the first letter of any of the previous.
- *
- * In SystemUI, buffers are provided by LogModule. Instances should be created using a SysUI
- * LogBufferFactory.
- *
- * @param name The name of this buffer, printed when the buffer is dumped and in some other
- * situations.
- * @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 maximum, it behaves like a ring buffer.
- */
-class LogBuffer
-@JvmOverloads
-constructor(
- private val name: String,
- private val maxSize: Int,
- private val logcatEchoTracker: LogcatEchoTracker,
- private val systrace: Boolean = true,
-) : MessageBuffer {
- private val buffer = RingBuffer(maxSize) { LogMessageImpl.create() }
-
- private val echoMessageQueue: BlockingQueue? =
- if (logcatEchoTracker.logInBackgroundThread) ArrayBlockingQueue(10) else null
-
- init {
- if (logcatEchoTracker.logInBackgroundThread && echoMessageQueue != null) {
- thread(start = true, name = "LogBuffer-$name", priority = Thread.NORM_PRIORITY) {
- try {
- while (true) {
- echoToDesiredEndpoints(echoMessageQueue.take())
- }
- } catch (e: InterruptedException) {
- Thread.currentThread().interrupt()
- }
- }
- }
- }
-
- var frozen = false
- private set
-
- private val mutable
- get() = !frozen && maxSize > 0
-
- /**
- * Logs a message to the log buffer
- *
- * May also log the message to logcat if echoing is enabled for this buffer or tag.
- *
- * The actual string of the log message is not constructed until it is needed. To accomplish
- * this, logging a message is a two-step process. First, a fresh instance of [LogMessage] is
- * obtained and is passed to the [messageInitializer]. The initializer stores any relevant data
- * on the message's fields. The message is then inserted into the buffer where it waits until it
- * is either pushed out by newer messages or it needs to printed. If and when this latter moment
- * occurs, the [messagePrinter] function is called on the message. It reads whatever data the
- * 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
- * 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
- * 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
- * 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
- * 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
- * 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
- * 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
- * new instance of the printer for each call, thwarting our attempts at avoiding any sort of
- * allocation.
- * @param exception Provide any exception that need to be logged. This is saved as
- * [LogMessage.exception]
- */
- @JvmOverloads
- inline fun log(
- tag: String,
- level: LogLevel,
- messageInitializer: MessageInitializer,
- noinline messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- ) {
- val message = obtain(tag, level, messagePrinter, exception)
- messageInitializer(message)
- commit(message)
- }
-
- /**
- * Logs a compile-time string constant [message] to the log buffer. Use sparingly.
- *
- * May also log the message to logcat if echoing is enabled for this buffer or tag. This is for
- * simpler use-cases where [message] is a compile time string constant. For use-cases where the
- * log message is built during runtime, use the [LogBuffer.log] overloaded method that takes in
- * an initializer and a message printer.
- *
- * Log buffers are limited by the number of entries, so logging more frequently will limit the
- * time window that the LogBuffer covers in a bug report. Richer logs, on the other hand, make a
- * bug report more actionable, so using the [log] with a messagePrinter to add more detail to
- * every log may do more to improve overall logging than adding more logs with this method.
- */
- @JvmOverloads
- fun log(
- tag: String,
- level: LogLevel,
- @CompileTimeConstant message: String,
- exception: Throwable? = null,
- ) = log(tag, level, { str1 = message }, { str1!! }, exception)
-
- /**
- * You should call [log] instead of this method.
- *
- * Obtains the next [LogMessage] from the ring buffer. If the buffer is not yet at max size,
- * grows the buffer by one.
- *
- * After calling [obtain], the message will now be at the end of the buffer. The caller must
- * store any relevant data on the message and then call [commit].
- */
- @Synchronized
- override fun obtain(
- tag: String,
- level: LogLevel,
- messagePrinter: MessagePrinter,
- exception: Throwable?,
- ): LogMessage {
- if (!mutable) {
- return FROZEN_MESSAGE
- }
- val message = buffer.advance()
- message.reset(tag, level, System.currentTimeMillis(), messagePrinter, exception)
- return message
- }
-
- /**
- * You should call [log] instead of this method.
- *
- * After acquiring a message via [obtain], call this method to signal to the buffer that you
- * have finished filling in its data fields. The message will be echoed to logcat if necessary.
- */
- @Synchronized
- override fun commit(message: LogMessage) {
- if (!mutable) {
- return
- }
- // Log in the background thread only if echoMessageQueue exists and has capacity (checking
- // capacity avoids the possibility of blocking this thread)
- if (echoMessageQueue != null && echoMessageQueue.remainingCapacity() > 0) {
- try {
- echoMessageQueue.put(message)
- } catch (e: InterruptedException) {
- // the background thread has been shut down, so just log on this one
- echoToDesiredEndpoints(message)
- }
- } else {
- echoToDesiredEndpoints(message)
- }
- }
-
- /** Sends message to echo after determining whether to use Logcat and/or systrace. */
- private fun echoToDesiredEndpoints(message: LogMessage) {
- val includeInLogcat =
- logcatEchoTracker.isBufferLoggable(name, message.level) ||
- logcatEchoTracker.isTagLoggable(message.tag, message.level)
- echo(message, toLogcat = includeInLogcat, toSystrace = systrace)
- }
-
- /** Converts the entire buffer to a newline-delimited string */
- @Synchronized
- fun dump(pw: PrintWriter, tailLength: Int) {
- val iterationStart =
- if (tailLength <= 0) {
- 0
- } else {
- max(0, buffer.size - tailLength)
- }
-
- for (i in iterationStart until buffer.size) {
- buffer[i].dump(pw)
- }
- }
-
- /**
- * "Freezes" the contents of the buffer, making it immutable until [unfreeze] is called. Calls
- * to [log], [obtain], and [commit] will not affect the buffer and will return dummy values if
- * necessary.
- */
- @Synchronized
- fun freeze() {
- if (!frozen) {
- log(TAG, LogLevel.DEBUG, { str1 = name }, { "$str1 frozen" })
- frozen = true
- }
- }
-
- /** Undoes the effects of calling [freeze]. */
- @Synchronized
- fun unfreeze() {
- if (frozen) {
- frozen = false
- log(TAG, LogLevel.DEBUG, { str1 = name }, { "$str1 unfrozen" })
- }
- }
-
- private fun echo(message: LogMessage, toLogcat: Boolean, toSystrace: Boolean) {
- if (toLogcat || toSystrace) {
- val strMessage = message.messagePrinter(message)
- if (toSystrace) {
- echoToSystrace(message, strMessage)
- }
- if (toLogcat) {
- echoToLogcat(message, strMessage)
- }
- }
- }
-
- private fun echoToSystrace(message: LogMessage, strMessage: String) {
- if (Trace.isTagEnabled(Trace.TRACE_TAG_APP)) {
- Trace.instantForTrack(
- Trace.TRACE_TAG_APP,
- "UI Events",
- "$name - ${message.level.shortString} ${message.tag}: $strMessage"
- )
- }
- }
-
- private fun echoToLogcat(message: LogMessage, strMessage: String) {
- when (message.level) {
- LogLevel.VERBOSE -> Log.v(message.tag, strMessage, message.exception)
- LogLevel.DEBUG -> Log.d(message.tag, strMessage, message.exception)
- LogLevel.INFO -> Log.i(message.tag, strMessage, message.exception)
- LogLevel.WARNING -> Log.w(message.tag, strMessage, message.exception)
- LogLevel.ERROR -> Log.e(message.tag, strMessage, message.exception)
- LogLevel.WTF -> Log.wtf(message.tag, strMessage, message.exception)
- }
- }
-}
-
-private const val TAG = "LogBuffer"
-private val FROZEN_MESSAGE = LogMessageImpl.create()
diff --git a/systemUILog/src/com/android/systemui/log/LogMessageImpl.kt b/systemUILog/src/com/android/systemui/log/LogMessageImpl.kt
deleted file mode 100644
index 33cc199e71..0000000000
--- a/systemUILog/src/com/android/systemui/log/LogMessageImpl.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log
-
-import com.android.systemui.log.core.LogLevel
-import com.android.systemui.log.core.LogMessage
-import com.android.systemui.log.core.MessagePrinter
-
-/** Recyclable implementation of [LogMessage]. */
-data class LogMessageImpl(
- override var level: LogLevel,
- override var tag: String,
- override var timestamp: Long,
- override var messagePrinter: MessagePrinter,
- override var exception: Throwable?,
- override var str1: String?,
- override var str2: String?,
- override var str3: String?,
- override var int1: Int,
- override var int2: Int,
- override var long1: Long,
- override var long2: Long,
- override var double1: Double,
- override var bool1: Boolean,
- override var bool2: Boolean,
- override var bool3: Boolean,
- override var bool4: Boolean,
-) : LogMessage {
-
- fun reset(
- tag: String,
- level: LogLevel,
- timestamp: Long,
- renderer: MessagePrinter,
- exception: Throwable? = null,
- ) {
- this.level = level
- this.tag = tag
- this.timestamp = timestamp
- this.messagePrinter = renderer
- this.exception = exception
- str1 = null
- str2 = null
- str3 = null
- int1 = 0
- int2 = 0
- long1 = 0
- long2 = 0
- double1 = 0.0
- bool1 = false
- bool2 = false
- bool3 = false
- bool4 = false
- }
-
- companion object Factory {
- fun create(): LogMessageImpl {
- return LogMessageImpl(
- LogLevel.DEBUG,
- DEFAULT_TAG,
- 0,
- DEFAULT_PRINTER,
- null,
- null,
- null,
- null,
- 0,
- 0,
- 0,
- 0,
- 0.0,
- false,
- false,
- false,
- false
- )
- }
- }
-}
-
-private const val DEFAULT_TAG = "UnknownTag"
-private val DEFAULT_PRINTER: MessagePrinter = { "Unknown message: $this" }
diff --git a/systemUILog/src/com/android/systemui/log/LogcatEchoTracker.kt b/systemUILog/src/com/android/systemui/log/LogcatEchoTracker.kt
deleted file mode 100644
index ae717df50f..0000000000
--- a/systemUILog/src/com/android/systemui/log/LogcatEchoTracker.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log
-
-import com.android.systemui.log.core.LogLevel
-
-/** Keeps track of which [LogBuffer] messages should also appear in logcat. */
-interface LogcatEchoTracker {
- /** Whether [bufferName] should echo messages of [level] or higher to logcat. */
- fun isBufferLoggable(bufferName: String, level: LogLevel): Boolean
-
- /** Whether [tagName] should echo messages of [level] or higher to logcat. */
- fun isTagLoggable(tagName: String, level: LogLevel): Boolean
-
- /** Whether to log messages in a background thread. */
- val logInBackgroundThread: Boolean
-}
diff --git a/systemUILog/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt b/systemUILog/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
deleted file mode 100644
index 9ff48cabc6..0000000000
--- a/systemUILog/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log
-
-import android.content.ContentResolver
-import android.database.ContentObserver
-import android.net.Uri
-import android.os.Handler
-import android.os.Looper
-import android.os.Trace
-import android.provider.Settings
-import com.android.systemui.log.core.LogLevel
-
-/**
- * Version of [LogcatEchoTracker] for debuggable builds
- *
- * The log level of individual buffers or tags can be controlled via global settings:
- * ```
- * # Echo any message to of or higher
- * $ adb shell settings put global systemui/buffer/
- *
- * # Echo any message of and of or higher
- * $ adb shell settings put global systemui/tag/
- * ```
- */
-class LogcatEchoTrackerDebug private constructor(private val contentResolver: ContentResolver) :
- LogcatEchoTracker {
- private val cachedBufferLevels: MutableMap = mutableMapOf()
- private val cachedTagLevels: MutableMap = mutableMapOf()
- override val logInBackgroundThread = true
-
- companion object Factory {
- @JvmStatic
- fun create(contentResolver: ContentResolver, mainLooper: Looper): LogcatEchoTrackerDebug {
- val tracker = LogcatEchoTrackerDebug(contentResolver)
- tracker.attach(mainLooper)
- return tracker
- }
- }
-
- private fun clearCache() {
- Trace.beginSection("LogcatEchoTrackerDebug#clearCache")
- cachedBufferLevels.clear()
- Trace.endSection()
- }
-
- private fun attach(mainLooper: Looper) {
- Trace.beginSection("LogcatEchoTrackerDebug#attach")
- contentResolver.registerContentObserver(
- Settings.Global.getUriFor(BUFFER_PATH),
- true,
- object : ContentObserver(Handler(mainLooper)) {
- override fun onChange(selfChange: Boolean, uri: Uri?) {
- super.onChange(selfChange, uri)
- clearCache()
- }
- }
- )
-
- contentResolver.registerContentObserver(
- Settings.Global.getUriFor(TAG_PATH),
- true,
- object : ContentObserver(Handler(mainLooper)) {
- override fun onChange(selfChange: Boolean, uri: Uri?) {
- super.onChange(selfChange, uri)
- clearCache()
- }
- }
- )
- Trace.endSection()
- }
-
- /** Whether [bufferName] should echo messages of [level] or higher to logcat. */
- @Synchronized
- override fun isBufferLoggable(bufferName: String, level: LogLevel): Boolean {
- return level.ordinal >= getLogLevel(bufferName, BUFFER_PATH, cachedBufferLevels).ordinal
- }
-
- /** Whether [tagName] should echo messages of [level] or higher to logcat. */
- @Synchronized
- override fun isTagLoggable(tagName: String, level: LogLevel): Boolean {
- return level >= getLogLevel(tagName, TAG_PATH, cachedTagLevels)
- }
-
- private fun getLogLevel(
- name: String,
- path: String,
- cache: MutableMap
- ): LogLevel {
- return cache[name] ?: readSetting("$path/$name").also { cache[name] = it }
- }
-
- private fun readSetting(path: String): LogLevel {
- return try {
- Trace.beginSection("LogcatEchoTrackerDebug#readSetting")
- parseProp(Settings.Global.getString(contentResolver, path))
- } catch (_: Settings.SettingNotFoundException) {
- DEFAULT_LEVEL
- } finally {
- Trace.endSection()
- }
- }
-
- private fun parseProp(propValue: String?): LogLevel {
- return when (propValue?.lowercase()) {
- "verbose" -> LogLevel.VERBOSE
- "v" -> LogLevel.VERBOSE
- "debug" -> LogLevel.DEBUG
- "d" -> LogLevel.DEBUG
- "info" -> LogLevel.INFO
- "i" -> LogLevel.INFO
- "warning" -> LogLevel.WARNING
- "warn" -> LogLevel.WARNING
- "w" -> LogLevel.WARNING
- "error" -> LogLevel.ERROR
- "e" -> LogLevel.ERROR
- "assert" -> LogLevel.WTF
- "wtf" -> LogLevel.WTF
- else -> DEFAULT_LEVEL
- }
- }
-}
-
-private val DEFAULT_LEVEL = LogLevel.WARNING
-private const val BUFFER_PATH = "systemui/buffer"
-private const val TAG_PATH = "systemui/tag"
diff --git a/systemUILog/src/com/android/systemui/log/LogcatEchoTrackerProd.kt b/systemUILog/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
deleted file mode 100644
index 044d97f92b..0000000000
--- a/systemUILog/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log
-
-import com.android.systemui.log.core.LogLevel
-
-/** Production version of [LogcatEchoTracker] that isn't configurable. */
-class LogcatEchoTrackerProd : LogcatEchoTracker {
- override val logInBackgroundThread = false
-
- override fun isBufferLoggable(bufferName: String, level: LogLevel): Boolean {
- return level >= LogLevel.WARNING
- }
-
- override fun isTagLoggable(tagName: String, level: LogLevel): Boolean {
- return level >= LogLevel.WARNING
- }
-}
diff --git a/systemUILog/src/com/android/systemui/log/core/LogLevel.kt b/systemUILog/src/com/android/systemui/log/core/LogLevel.kt
deleted file mode 100644
index d30d8e9fe0..0000000000
--- a/systemUILog/src/com/android/systemui/log/core/LogLevel.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log.core
-
-import android.util.Log
-
-/** Enum version of @Log.Level */
-enum class LogLevel(@Log.Level val nativeLevel: Int, val shortString: String) {
- VERBOSE(Log.VERBOSE, "V"),
- DEBUG(Log.DEBUG, "D"),
- INFO(Log.INFO, "I"),
- WARNING(Log.WARN, "W"),
- ERROR(Log.ERROR, "E"),
- WTF(Log.ASSERT, "WTF")
-}
diff --git a/systemUILog/src/com/android/systemui/log/core/LogMessage.kt b/systemUILog/src/com/android/systemui/log/core/LogMessage.kt
deleted file mode 100644
index 3bd6473738..0000000000
--- a/systemUILog/src/com/android/systemui/log/core/LogMessage.kt
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log.core
-
-import android.icu.text.SimpleDateFormat
-import java.io.PrintWriter
-import java.util.Locale
-
-/**
- * Generic data class for storing messages logged to a [LogBuffer]
- *
- * Each LogMessage has a few standard fields ([level], [tag], and [timestamp]). The rest are generic
- * data slots that may or may not be used, depending on the nature of the specific message being
- * logged.
- *
- * When a message is logged, the code doing the logging stores data in one or more of the generic
- * fields ([str1], [int1], etc). When it comes time to dump the message to logcat/bugreport/etc, the
- * [messagePrinter] function reads the data stored in the generic fields and converts that to a
- * human- readable string. Thus, for every log type there must be a specialized initializer function
- * that stores data specific to that log type and a specialized printer function that prints that
- * data.
- *
- * See [LogBuffer.log] for more information.
- */
-interface LogMessage {
- val level: LogLevel
- val tag: String
- val timestamp: Long
- val messagePrinter: MessagePrinter
- val exception: Throwable?
-
- var str1: String?
- var str2: String?
- var str3: String?
- var int1: Int
- var int2: Int
- var long1: Long
- var long2: Long
- var double1: Double
- var bool1: Boolean
- var bool2: Boolean
- var bool3: Boolean
- var bool4: Boolean
-
- /** Function that dumps the [LogMessage] to the provided [writer]. */
- fun dump(writer: PrintWriter) {
- val formattedTimestamp = DATE_FORMAT.format(timestamp)
- val shortLevel = level.shortString
- val messageToPrint = messagePrinter(this)
- printLikeLogcat(writer, formattedTimestamp, shortLevel, tag, messageToPrint)
- exception?.printStackTrace(writer)
- }
-}
-
-/**
- * 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.
- */
-typealias MessageInitializer = LogMessage.() -> Unit
-
-/**
- * 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 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 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 allocation.
- */
-typealias MessagePrinter = LogMessage.() -> String
-
-private fun printLikeLogcat(
- pw: PrintWriter,
- formattedTimestamp: String,
- shortLogLevel: String,
- tag: String,
- message: String
-) {
- pw.print(formattedTimestamp)
- pw.print(" ")
- pw.print(shortLogLevel)
- pw.print(" ")
- pw.print(tag)
- pw.print(": ")
- pw.println(message)
-}
-
-private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
diff --git a/systemUILog/src/com/android/systemui/log/core/Logger.kt b/systemUILog/src/com/android/systemui/log/core/Logger.kt
deleted file mode 100644
index 5729ab2704..0000000000
--- a/systemUILog/src/com/android/systemui/log/core/Logger.kt
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log.core
-
-import com.google.errorprone.annotations.CompileTimeConstant
-
-/** Logs messages to the [MessageBuffer] with [tag]. */
-open class Logger(val buffer: MessageBuffer, val tag: String) {
- /**
- * Logs a message to the buffer.
- *
- * The actual string of the log message is not constructed until it is needed. To accomplish
- * this, logging a message is a two-step process. First, a fresh instance of [LogMessage] is
- * obtained and is passed to the [messageInitializer]. The initializer stores any relevant data
- * on the message's fields. The message is then inserted into the buffer where it waits until it
- * is either pushed out by newer messages or it needs to printed. If and when this latter moment
- * occurs, the [messagePrinter] function is called on the message. It reads whatever data the
- * initializer stored and converts it to a human-readable log message.
- *
- * @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.
- * 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.
- * @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
- * 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 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 allocation.
- * @param exception Provide any exception that need to be logged. This is saved as
- * [LogMessage.exception]
- * @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.
- */
- @JvmOverloads
- inline fun log(
- level: LogLevel,
- noinline messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- messageInitializer: MessageInitializer,
- ) {
- val message = buffer.obtain(tag, level, messagePrinter, exception)
- messageInitializer(message)
- buffer.commit(message)
- }
-
- /**
- * Logs a compile-time string constant [message] to the log buffer. Use sparingly.
- *
- * This is for simpler use-cases where [message] is a compile time string constant. For
- * use-cases where the log message is built during runtime, use the [log] overloaded method that
- * takes in an initializer and a message printer.
- *
- * Buffers are limited by the number of entries, so logging more frequently will limit the time
- * window that the [MessageBuffer] covers in a bug report. Richer logs, on the other hand, make
- * a bug report more actionable, so using the [log] with a [MessagePrinter] to add more details
- * to every log may do more to improve overall logging than adding more logs with this method.
- */
- @JvmOverloads
- fun log(
- level: LogLevel,
- @CompileTimeConstant message: String,
- exception: Throwable? = null,
- ) = log(level, { str1!! }, exception) { str1 = message }
-
- /**
- * Logs a message to the buffer at [LogLevel.VERBOSE].
- *
- * @see log
- */
- @JvmOverloads
- inline fun v(
- noinline messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- messageInitializer: MessageInitializer,
- ) = log(LogLevel.VERBOSE, messagePrinter, exception, messageInitializer)
-
- /**
- * Logs a compile-time string constant [message] to the log buffer at [LogLevel.VERBOSE]. Use
- * sparingly.
- *
- * @see log
- */
- @JvmOverloads
- fun v(
- @CompileTimeConstant message: String,
- exception: Throwable? = null,
- ) = log(LogLevel.VERBOSE, message, exception)
-
- /**
- * Logs a message to the buffer at [LogLevel.DEBUG].
- *
- * @see log
- */
- @JvmOverloads
- inline fun d(
- noinline messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- messageInitializer: MessageInitializer,
- ) = log(LogLevel.DEBUG, messagePrinter, exception, messageInitializer)
-
- /**
- * Logs a compile-time string constant [message] to the log buffer at [LogLevel.DEBUG]. Use
- * sparingly.
- *
- * @see log
- */
- @JvmOverloads
- fun d(
- @CompileTimeConstant message: String,
- exception: Throwable? = null,
- ) = log(LogLevel.DEBUG, message, exception)
-
- /**
- * Logs a message to the buffer at [LogLevel.INFO].
- *
- * @see log
- */
- @JvmOverloads
- inline fun i(
- noinline messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- messageInitializer: MessageInitializer,
- ) = log(LogLevel.INFO, messagePrinter, exception, messageInitializer)
-
- /**
- * Logs a compile-time string constant [message] to the log buffer at [LogLevel.INFO]. Use
- * sparingly.
- *
- * @see log
- */
- @JvmOverloads
- fun i(
- @CompileTimeConstant message: String,
- exception: Throwable? = null,
- ) = log(LogLevel.INFO, message, exception)
-
- /**
- * Logs a message to the buffer at [LogLevel.WARNING].
- *
- * @see log
- */
- @JvmOverloads
- inline fun w(
- noinline messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- messageInitializer: MessageInitializer,
- ) = log(LogLevel.WARNING, messagePrinter, exception, messageInitializer)
-
- /**
- * Logs a compile-time string constant [message] to the log buffer at [LogLevel.WARNING]. Use
- * sparingly.
- *
- * @see log
- */
- @JvmOverloads
- fun w(
- @CompileTimeConstant message: String,
- exception: Throwable? = null,
- ) = log(LogLevel.WARNING, message, exception)
-
- /**
- * Logs a message to the buffer at [LogLevel.ERROR].
- *
- * @see log
- */
- @JvmOverloads
- inline fun e(
- noinline messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- messageInitializer: MessageInitializer,
- ) = log(LogLevel.ERROR, messagePrinter, exception, messageInitializer)
-
- /**
- * Logs a compile-time string constant [message] to the log buffer at [LogLevel.ERROR]. Use
- * sparingly.
- *
- * @see log
- */
- @JvmOverloads
- fun e(
- @CompileTimeConstant message: String,
- exception: Throwable? = null,
- ) = log(LogLevel.ERROR, message, exception)
-
- /**
- * Logs a message to the buffer at [LogLevel.WTF].
- *
- * @see log
- */
- @JvmOverloads
- inline fun wtf(
- noinline messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- messageInitializer: MessageInitializer,
- ) = log(LogLevel.WTF, messagePrinter, exception, messageInitializer)
-
- /**
- * Logs a compile-time string constant [message] to the log buffer at [LogLevel.WTF]. Use
- * sparingly.
- *
- * @see log
- */
- @JvmOverloads
- fun wtf(
- @CompileTimeConstant message: String,
- exception: Throwable? = null,
- ) = log(LogLevel.WTF, message, exception)
-}
diff --git a/systemUILog/src/com/android/systemui/log/core/MessageBuffer.kt b/systemUILog/src/com/android/systemui/log/core/MessageBuffer.kt
deleted file mode 100644
index bb91633c4d..0000000000
--- a/systemUILog/src/com/android/systemui/log/core/MessageBuffer.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log.core
-
-/**
- * [MessageBuffer] is an interface that represents a buffer of log messages, and provides methods to
- * [obtain] a log message and [commit] it to the buffer.
- */
-interface MessageBuffer {
- /**
- * Obtains the next [LogMessage] from the buffer.
- *
- * After calling [obtain], the caller must store any relevant data on the message and then call
- * [commit].
- */
- fun obtain(
- tag: String,
- level: LogLevel,
- messagePrinter: MessagePrinter,
- exception: Throwable? = null,
- ): LogMessage
-
- /**
- * After acquiring a log message via [obtain], call this method to signal to the buffer that
- * data fields have been filled.
- */
- fun commit(message: LogMessage)
-}
diff --git a/systemUIPlugin/Android.bp b/systemUIPlugin/Android.bp
deleted file mode 100644
index bb47a2f472..0000000000
--- a/systemUIPlugin/Android.bp
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
-}
-
-java_library {
-
- name: "SystemUIPluginLib",
-
- srcs: [
- "src/**/*.java",
- "src/**/*.kt",
- "bcsmartspace/src/**/*.java",
- "bcsmartspace/src/**/*.kt",
- ],
-
- // If you add a static lib here, you may need to also add the package to the ClassLoaderFilter
- // in PluginInstance. That will ensure that loaded plugins have access to the related classes.
- // You should also add it to proguard_common.flags so that proguard does not remove the portions
- // of the library which are used by the plugins but not by systemui itself.
- static_libs: [
- "androidx.annotation_annotation",
- "PluginCoreLib",
- "SystemUIAnimationLib",
- "SystemUICommon",
- "SystemUILogLib",
- ],
-
-}
-
-android_app {
-
- // Dummy to generate .toc files.
- name: "PluginDummyLib",
- platform_apis: true,
- srcs: ["src/**/*.java"],
-
- libs: ["SystemUIPluginLib"],
-
- optimize: {
- enabled: false,
- },
-
-}
diff --git a/systemUIPlugin/AndroidManifest.xml b/systemUIPlugin/AndroidManifest.xml
deleted file mode 100644
index 811595ade9..0000000000
--- a/systemUIPlugin/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
diff --git a/systemUIPlugin/ExamplePlugin/Android.bp b/systemUIPlugin/ExamplePlugin/Android.bp
deleted file mode 100644
index 3f0fdedb57..0000000000
--- a/systemUIPlugin/ExamplePlugin/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
-}
-
-android_app {
-
- name: "ExamplePlugin",
-
- libs: ["SystemUIPluginLib"],
-
- certificate: "platform",
- optimize: {
- enabled: false,
- },
-
- srcs: ["src/**/*.java"],
-
- platform_apis: true,
-}
diff --git a/systemUIPlugin/ExamplePlugin/AndroidManifest.xml b/systemUIPlugin/ExamplePlugin/AndroidManifest.xml
deleted file mode 100644
index e9e844124e..0000000000
--- a/systemUIPlugin/ExamplePlugin/AndroidManifest.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/systemUIPlugin/ExamplePlugin/res/layout/colored_overlay.xml b/systemUIPlugin/ExamplePlugin/res/layout/colored_overlay.xml
deleted file mode 100644
index b2910cb19b..0000000000
--- a/systemUIPlugin/ExamplePlugin/res/layout/colored_overlay.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
diff --git a/systemUIPlugin/ExamplePlugin/res/layout/plugin_settings.xml b/systemUIPlugin/ExamplePlugin/res/layout/plugin_settings.xml
deleted file mode 100644
index eb90283f08..0000000000
--- a/systemUIPlugin/ExamplePlugin/res/layout/plugin_settings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
diff --git a/systemUIPlugin/ExamplePlugin/res/values/strings.xml b/systemUIPlugin/ExamplePlugin/res/values/strings.xml
deleted file mode 100644
index a0bfe849e5..0000000000
--- a/systemUIPlugin/ExamplePlugin/res/values/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
- Plugin settings go here
- Overlay Plugin
-
-
diff --git a/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/CustomView.java b/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/CustomView.java
deleted file mode 100644
index 5fdbbf989b..0000000000
--- a/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/CustomView.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugin.testoverlayplugin;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-
-/**
- * View with some logging to show that its being run.
- */
-public class CustomView extends View {
-
- private static final String TAG = "CustomView";
-
- public CustomView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- Log.d(TAG, "new instance");
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- Log.d(TAG, "onAttachedToWindow");
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- Log.d(TAG, "onDetachedFromWindow");
- }
-}
diff --git a/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/PluginSettings.java b/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/PluginSettings.java
deleted file mode 100644
index cf39075d95..0000000000
--- a/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/PluginSettings.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugin.testoverlayplugin;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.os.Bundle;
-
-/**
- * DO NOT Reference Plugin interfaces here, this runs in the plugin APK's process
- * and is only for modifying settings.
- */
-public class PluginSettings extends Activity {
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.plugin_settings);
- }
-}
diff --git a/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/SampleOverlayPlugin.java b/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/SampleOverlayPlugin.java
deleted file mode 100644
index 79a0c35990..0000000000
--- a/systemUIPlugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/SampleOverlayPlugin.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugin.testoverlayplugin;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import android.view.ViewTreeObserver.InternalInsetsInfo;
-import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
-import com.android.systemui.plugins.OverlayPlugin;
-import com.android.systemui.plugins.annotations.Requires;
-
-@Requires(target = OverlayPlugin.class, version = OverlayPlugin.VERSION)
-public class SampleOverlayPlugin implements OverlayPlugin {
- private static final String TAG = "SampleOverlayPlugin";
- private Context mPluginContext;
-
- private View mStatusBarView;
- private View mNavBarView;
- private boolean mInputSetup;
- private boolean mCollapseDesired;
- private float mStatusBarHeight;
-
- @Override
- public void onCreate(Context sysuiContext, Context pluginContext) {
- Log.d(TAG, "onCreate");
- mPluginContext = pluginContext;
- }
-
- @Override
- public void onDestroy() {
- if (mInputSetup) {
- mStatusBarView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
- onComputeInternalInsetsListener);
- }
- Log.d(TAG, "onDestroy");
- if (mStatusBarView != null) {
- mStatusBarView.post(
- () -> ((ViewGroup) mStatusBarView.getParent()).removeView(mStatusBarView));
- }
- if (mNavBarView != null) {
- mNavBarView.post(() -> ((ViewGroup) mNavBarView.getParent()).removeView(mNavBarView));
- }
- }
-
- @Override
- public void setup(View statusBar, View navBar) {
- Log.d(TAG, "Setup");
-
- int id = mPluginContext.getResources().getIdentifier("status_bar_height", "dimen",
- "android");
- mStatusBarHeight = mPluginContext.getResources().getDimension(id);
- if (statusBar instanceof ViewGroup) {
- mStatusBarView = LayoutInflater.from(mPluginContext)
- .inflate(R.layout.colored_overlay, (ViewGroup) statusBar, false);
- ((ViewGroup) statusBar).addView(mStatusBarView);
- }
- if (navBar instanceof ViewGroup) {
- mNavBarView = LayoutInflater.from(mPluginContext)
- .inflate(R.layout.colored_overlay, (ViewGroup) navBar, false);
- ((ViewGroup) navBar).addView(mNavBarView);
- }
- }
-
- @Override
- public void setCollapseDesired(boolean collapseDesired) {
- mCollapseDesired = collapseDesired;
- }
-
- @Override
- public boolean holdStatusBarOpen() {
- if (!mInputSetup) {
- mInputSetup = true;
- mStatusBarView.getViewTreeObserver().addOnComputeInternalInsetsListener(
- onComputeInternalInsetsListener);
- }
- return true;
- }
-
- final OnComputeInternalInsetsListener onComputeInternalInsetsListener = inoutInfo -> {
- inoutInfo.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- if (mCollapseDesired) {
- inoutInfo.touchableRegion.set(new Rect(0, 0, 50000, (int) mStatusBarHeight));
- } else {
- inoutInfo.touchableRegion.set(new Rect(0, 0, 50000, 50000));
- }
- };
-}
diff --git a/systemUIPlugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt b/systemUIPlugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt
deleted file mode 100644
index 509f022310..0000000000
--- a/systemUIPlugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceConfigPlugin.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins
-
-// TODO(b/265360975): Evaluate this plugin approach.
-/** Plugin to provide BC smartspace configuration */
-interface BcSmartspaceConfigPlugin {
- /** Gets default date/weather disabled status. */
- val isDefaultDateWeatherDisabled: Boolean
-}
diff --git a/systemUIPlugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/systemUIPlugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
deleted file mode 100644
index 64c0f99f4b..0000000000
--- a/systemUIPlugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.app.PendingIntent;
-import android.app.smartspace.SmartspaceAction;
-import android.app.smartspace.SmartspaceTarget;
-import android.app.smartspace.SmartspaceTargetEvent;
-import android.app.smartspace.uitemplatedata.TapAction;
-import android.content.ActivityNotFoundException;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.os.Parcelable;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.Nullable;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-import java.util.List;
-
-/**
- * Interface to provide SmartspaceTargets to BcSmartspace.
- */
-@ProvidesInterface(action = BcSmartspaceDataPlugin.ACTION, version = BcSmartspaceDataPlugin.VERSION)
-public interface BcSmartspaceDataPlugin extends Plugin {
- String UI_SURFACE_LOCK_SCREEN_AOD = "lockscreen";
- String UI_SURFACE_HOME_SCREEN = "home";
- String UI_SURFACE_MEDIA = "media_data_manager";
- String UI_SURFACE_DREAM = "dream";
-
- String ACTION = "com.android.systemui.action.PLUGIN_BC_SMARTSPACE_DATA";
- int VERSION = 1;
- String TAG = "BcSmartspaceDataPlugin";
-
- /** Register a listener to get Smartspace data. */
- default void registerListener(SmartspaceTargetListener listener) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /** Unregister a listener. */
- default void unregisterListener(SmartspaceTargetListener listener) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /** Register a SmartspaceEventNotifier. */
- default void registerSmartspaceEventNotifier(SmartspaceEventNotifier notifier) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /** Push a SmartspaceTargetEvent to the SmartspaceEventNotifier. */
- default void notifySmartspaceEvent(SmartspaceTargetEvent event) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /** Allows for notifying the SmartspaceSession of SmartspaceTargetEvents. */
- interface SmartspaceEventNotifier {
- /** Pushes a given SmartspaceTargetEvent to the SmartspaceSession. */
- void notifySmartspaceEvent(SmartspaceTargetEvent event);
- }
-
- /**
- * Create a view to be shown within the parent. Do not add the view, as the parent
- * will be responsible for correctly setting the LayoutParams
- */
- default SmartspaceView getView(ViewGroup parent) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /**
- * As the smartspace view becomes available, allow listeners to receive an event.
- */
- default void addOnAttachStateChangeListener(View.OnAttachStateChangeListener listener) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /** Updates Smartspace data and propagates it to any listeners. */
- default void onTargetsAvailable(List targets) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /** Provides Smartspace data to registered listeners. */
- interface SmartspaceTargetListener {
- /** Each Parcelable is a SmartspaceTarget that represents a card. */
- void onSmartspaceTargetsUpdated(List extends Parcelable> targets);
- }
-
- /** View to which this plugin can be registered, in order to get updates. */
- interface SmartspaceView {
- void registerDataProvider(BcSmartspaceDataPlugin plugin);
-
- /**
- * Sets {@link BcSmartspaceConfigPlugin}.
- */
- default void registerConfigProvider(BcSmartspaceConfigPlugin configProvider) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /**
- * Primary color for unprotected text
- */
- void setPrimaryTextColor(int color);
-
- /**
- * Set the UI surface for the cards. Should be called immediately after the view is created.
- */
- void setUiSurface(String uiSurface);
-
- /**
- * Range [0.0 - 1.0] when transitioning from Lockscreen to/from AOD
- */
- void setDozeAmount(float amount);
-
- /**
- * Set if dozing is true or false
- */
- default void setDozing(boolean dozing) {}
-
- /**
- * Set if split shade enabled
- */
- default void setSplitShadeEnabled(boolean enabled) {}
-
- /**
- * Set the current keyguard bypass enabled status.
- */
- default void setKeyguardBypassEnabled(boolean enabled) {}
-
- /**
- * Overrides how Intents/PendingIntents gets launched. Mostly to support auth from
- * the lockscreen.
- */
- void setIntentStarter(IntentStarter intentStarter);
-
- /**
- * When on the lockscreen, use the FalsingManager to help detect errant touches
- */
- void setFalsingManager(com.android.systemui.plugins.FalsingManager falsingManager);
-
- /**
- * Set or clear Do Not Disturb information.
- */
- default void setDnd(@Nullable Drawable image, @Nullable String description) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /**
- * Set or clear next alarm information
- */
- default void setNextAlarm(@Nullable Drawable image, @Nullable String description) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /**
- * Set or clear device media playing
- */
- default void setMediaTarget(@Nullable SmartspaceTarget target) {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /**
- * Get the index of the currently selected page.
- */
- default int getSelectedPage() {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
-
- /**
- * Return the top padding value from the currently visible card, or 0 if there is no current
- * card.
- */
- default int getCurrentCardTopPadding() {
- throw new UnsupportedOperationException("Not implemented by " + getClass());
- }
- }
-
- /** Interface for launching Intents, which can differ on the lockscreen */
- interface IntentStarter {
- default void startFromAction(SmartspaceAction action, View v, boolean showOnLockscreen) {
- try {
- if (action.getIntent() != null) {
- startIntent(v, action.getIntent(), showOnLockscreen);
- } else if (action.getPendingIntent() != null) {
- startPendingIntent(v, action.getPendingIntent(), showOnLockscreen);
- }
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "Could not launch intent for action: " + action, e);
- }
- }
-
- default void startFromAction(TapAction action, View v, boolean showOnLockscreen) {
- try {
- if (action.getIntent() != null) {
- startIntent(v, action.getIntent(), showOnLockscreen);
- } else if (action.getPendingIntent() != null) {
- startPendingIntent(v, action.getPendingIntent(), showOnLockscreen);
- }
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "Could not launch intent for action: " + action, e);
- }
- }
-
- /** Start the intent */
- void startIntent(View v, Intent i, boolean showOnLockscreen);
-
- /** Start the PendingIntent */
- void startPendingIntent(View v, PendingIntent pi, boolean showOnLockscreen);
- }
-}
diff --git a/systemUIPlugin/build.gradle b/systemUIPlugin/build.gradle
deleted file mode 100644
index 5b6b034dee..0000000000
--- a/systemUIPlugin/build.gradle
+++ /dev/null
@@ -1,28 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'org.jetbrains.kotlin.android'
-}
-
-android {
- namespace "com.android.systemui.plugins"
- buildFeatures {
- aidl true
- }
- sourceSets {
- main {
- java.srcDirs = ['src']
- aidl.srcDirs = ['src']
- manifest.srcFile 'AndroidManifest.xml'
- res.srcDirs = ['res']
- }
- }
-}
-
-addFrameworkJar('framework-15.jar')
-compileOnlyCommonJars()
-
-dependencies {
- compileOnly projects.systemUIPluginCore
- compileOnly projects.systemUILog
- compileOnly projects.systemUIAnim
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/ActivityStarter.java b/systemUIPlugin/src/com/android/systemui/plugins/ActivityStarter.java
deleted file mode 100644
index 9cc87fde12..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.view.View;
-
-import com.android.systemui.animation.ActivityLaunchAnimator;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * An interface to start activities. This is used as a callback from the views to
- * {@link PhoneStatusBar} to allow custom handling for starting the activity, i.e. dismissing the
- * Keyguard.
- */
-@ProvidesInterface(version = ActivityStarter.VERSION)
-public interface ActivityStarter {
- int VERSION = 2;
-
- void startPendingIntentDismissingKeyguard(PendingIntent intent);
-
- /**
- * Similar to {@link #startPendingIntentDismissingKeyguard(PendingIntent)}, but allows
- * you to specify the callback that is executed on the UI thread after the intent is sent.
- */
- void startPendingIntentDismissingKeyguard(PendingIntent intent,
- Runnable intentSentUiThreadCallback);
-
- /**
- * Similar to {@link #startPendingIntentDismissingKeyguard(PendingIntent, Runnable)}, but also
- * specifies an associated view that should be used for the activity launch animation.
- */
- void startPendingIntentDismissingKeyguard(PendingIntent intent,
- Runnable intentSentUiThreadCallback, @Nullable View associatedView);
-
- /**
- * Similar to {@link #startPendingIntentDismissingKeyguard(PendingIntent, Runnable)}, but also
- * specifies an animation controller that should be used for the activity launch animation.
- */
- void startPendingIntentDismissingKeyguard(PendingIntent intent,
- Runnable intentSentUiThreadCallback,
- @Nullable ActivityLaunchAnimator.Controller animationController);
-
- /**
- * The intent flag can be specified in startActivity().
- */
- void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags);
- void startActivity(Intent intent, boolean dismissShade);
- default void startActivity(Intent intent, boolean dismissShade,
- @Nullable ActivityLaunchAnimator.Controller animationController) {
- startActivity(intent, dismissShade, animationController,
- false /* showOverLockscreenWhenLocked */);
- }
-
- void startActivity(Intent intent, boolean dismissShade,
- @Nullable ActivityLaunchAnimator.Controller animationController,
- boolean showOverLockscreenWhenLocked);
- void startActivity(Intent intent, boolean dismissShade,
- @Nullable ActivityLaunchAnimator.Controller animationController,
- boolean showOverLockscreenWhenLocked, UserHandle userHandle);
- void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade);
- void startActivity(Intent intent, boolean dismissShade, Callback callback);
- void postStartActivityDismissingKeyguard(Intent intent, int delay);
- void postStartActivityDismissingKeyguard(Intent intent, int delay,
- @Nullable ActivityLaunchAnimator.Controller animationController);
-
- /** Posts a start activity intent that dismisses keyguard. */
- void postStartActivityDismissingKeyguard(Intent intent, int delay,
- @Nullable ActivityLaunchAnimator.Controller animationController,
- @Nullable String customMessage);
- void postStartActivityDismissingKeyguard(PendingIntent intent);
-
- /**
- * Similar to {@link #postStartActivityDismissingKeyguard(PendingIntent)}, but also specifies an
- * animation controller that should be used for the activity launch animation.
- */
- void postStartActivityDismissingKeyguard(PendingIntent intent,
- @Nullable ActivityLaunchAnimator.Controller animationController);
-
- void postQSRunnableDismissingKeyguard(Runnable runnable);
-
- void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
- boolean afterKeyguardGone);
-
- /** Authenticates if needed and dismisses keyguard to execute an action. */
- void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
- boolean afterKeyguardGone, @Nullable String customMessage);
-
- /** Starts an activity and dismisses keyguard. */
- void startActivityDismissingKeyguard(Intent intent,
- boolean onlyProvisioned,
- boolean dismissShade);
-
- /** Starts an activity and dismisses keyguard. */
- void startActivityDismissingKeyguard(Intent intent,
- boolean onlyProvisioned,
- boolean dismissShade,
- boolean disallowEnterPictureInPictureWhileLaunching,
- Callback callback,
- int flags,
- @Nullable ActivityLaunchAnimator.Controller animationController,
- UserHandle userHandle);
-
- /** Execute a runnable after dismissing keyguard. */
- void executeRunnableDismissingKeyguard(Runnable runnable,
- Runnable cancelAction,
- boolean dismissShade,
- boolean afterKeyguardGone,
- boolean deferred);
-
- /** Execute a runnable after dismissing keyguard. */
- void executeRunnableDismissingKeyguard(
- Runnable runnable,
- Runnable cancelAction,
- boolean dismissShade,
- boolean afterKeyguardGone,
- boolean deferred,
- boolean willAnimateOnKeyguard,
- @Nullable String customMessage);
-
- /** Whether we should animate an activity launch. */
- boolean shouldAnimateLaunch(boolean isActivityIntent);
-
- interface Callback {
- void onActivityStarted(int resultCode);
- }
-
- interface OnDismissAction {
- /**
- * @return {@code true} if the dismiss should be deferred. When returning true, make sure to
- * call {@link com.android.keyguard.ViewMediatorCallback#readyForKeyguardDone()}
- * *after* returning to start hiding the keyguard.
- */
- boolean onDismiss();
-
- /**
- * Whether running this action when we are locked will start an animation on the keyguard.
- */
- default boolean willRunAnimationOnKeyguard() {
- return false;
- }
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/systemUIPlugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
deleted file mode 100644
index e2f4793b8f..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.android.systemui.plugins
-
-import android.content.res.Resources
-import android.graphics.Rect
-import android.graphics.drawable.Drawable
-import android.view.View
-import com.android.internal.annotations.Keep
-import com.android.systemui.log.core.MessageBuffer
-import com.android.systemui.plugins.annotations.ProvidesInterface
-import java.io.PrintWriter
-import java.util.Locale
-import java.util.TimeZone
-import org.json.JSONObject
-
-/** Identifies a clock design */
-typealias ClockId = String
-
-/** A Plugin which exposes the ClockProvider interface */
-@ProvidesInterface(action = ClockProviderPlugin.ACTION, version = ClockProviderPlugin.VERSION)
-interface ClockProviderPlugin : Plugin, ClockProvider {
- companion object {
- const val ACTION = "com.android.systemui.action.PLUGIN_CLOCK_PROVIDER"
- const val VERSION = 1
- }
-}
-
-/** Interface for building clocks and providing information about those clocks */
-interface ClockProvider {
- /** Returns metadata for all clocks this provider knows about */
- fun getClocks(): List
-
- /** Initializes and returns the target clock design */
- @Deprecated("Use overload with ClockSettings")
- fun createClock(id: ClockId): ClockController {
- return createClock(ClockSettings(id, null))
- }
-
- /** Initializes and returns the target clock design */
- fun createClock(settings: ClockSettings): ClockController
-
- /** A static thumbnail for rendering in some examples */
- fun getClockThumbnail(id: ClockId): Drawable?
-}
-
-/** Interface for controlling an active clock */
-interface ClockController {
- /** A small version of the clock, appropriate for smaller viewports */
- val smallClock: ClockFaceController
-
- /** A large version of the clock, appropriate when a bigger viewport is available */
- val largeClock: ClockFaceController
-
- /** Determines the way the hosting app should behave when rendering either clock face */
- val config: ClockConfig
-
- /** Events that clocks may need to respond to */
- val events: ClockEvents
-
- /** Initializes various rendering parameters. If never called, provides reasonable defaults. */
- fun initialize(
- resources: Resources,
- dozeFraction: Float,
- foldFraction: Float,
- )
-
- /** Optional method for dumping debug information */
- fun dump(pw: PrintWriter)
-}
-
-/** Interface for a specific clock face version rendered by the clock */
-interface ClockFaceController {
- /** View that renders the clock face */
- val view: View
-
- /** Determines the way the hosting app should behave when rendering this clock face */
- val config: ClockFaceConfig
-
- /** Events specific to this clock face */
- val events: ClockFaceEvents
-
- /** Triggers for various animations */
- val animations: ClockAnimations
-
- /** Some clocks may log debug information */
- var messageBuffer: MessageBuffer?
-}
-
-/** Events that should call when various rendering parameters change */
-interface ClockEvents {
- /** Call whenever timezone changes */
- fun onTimeZoneChanged(timeZone: TimeZone)
-
- /** Call whenever the text time format changes (12hr vs 24hr) */
- fun onTimeFormatChanged(is24Hr: Boolean)
-
- /** Call whenever the locale changes */
- fun onLocaleChanged(locale: Locale)
-
- /** Call whenever the color palette should update */
- fun onColorPaletteChanged(resources: Resources)
-
- /** Call if the seed color has changed and should be updated */
- fun onSeedColorChanged(seedColor: Int?)
-
- /** Call whenever the weather data should update */
- fun onWeatherDataChanged(data: WeatherData)
-}
-
-/** Methods which trigger various clock animations */
-interface ClockAnimations {
- /** Runs an enter animation (if any) */
- fun enter()
-
- /** Sets how far into AOD the device currently is. */
- fun doze(fraction: Float)
-
- /** Sets how far into the folding animation the device is. */
- fun fold(fraction: Float)
-
- /** Runs the battery animation (if any). */
- fun charge()
-
- /**
- * Runs when the clock's position changed during the move animation.
- *
- * @param fromLeft the [View.getLeft] position of the clock, before it started moving.
- * @param direction the direction in which it is moving. A positive number means right, and
- * negative means left.
- * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
- * it finished moving.
- */
- fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float)
-
- /**
- * Runs when swiping clock picker, swipingFraction: 1.0 -> clock is scaled up in the preview,
- * 0.0 -> clock is scaled down in the shade; previewRatio is previewSize / screenSize
- */
- fun onPickerCarouselSwiping(swipingFraction: Float)
-}
-
-/** Events that have specific data about the related face */
-interface ClockFaceEvents {
- /** Call every time tick */
- fun onTimeTick()
-
- /**
- * Region Darkness specific to the clock face.
- * - isRegionDark = dark theme -> clock should be light
- * - !isRegionDark = light theme -> clock should be dark
- */
- fun onRegionDarknessChanged(isRegionDark: Boolean)
-
- /**
- * Call whenever font settings change. Pass in a target font size in pixels. The specific clock
- * design is allowed to ignore this target size on a case-by-case basis.
- */
- fun onFontSettingChanged(fontSizePx: Float)
-
- /**
- * Target region information for the clock face. For small clock, this will match the bounds of
- * the parent view mostly, but have a target height based on the height of the default clock.
- * For large clocks, the parent view is the entire device size, but most clocks will want to
- * render within the centered targetRect to avoid obstructing other elements. The specified
- * targetRegion is relative to the parent view.
- */
- fun onTargetRegionChanged(targetRegion: Rect?)
-
- /** Called to notify the clock about its display. */
- fun onSecondaryDisplayChanged(onSecondaryDisplay: Boolean)
-}
-
-/** Tick rates for clocks */
-enum class ClockTickRate(val value: Int) {
- PER_MINUTE(2), // Update the clock once per minute.
- PER_SECOND(1), // Update the clock once per second.
- PER_FRAME(0), // Update the clock every second.
-}
-
-/** Some data about a clock design */
-data class ClockMetadata(
- val clockId: ClockId,
- val name: String,
-) {
- constructor(clockId: ClockId) : this(clockId, clockId) {}
-}
-
-/** Render configuration for the full clock. Modifies the way systemUI behaves with this clock. */
-data class ClockConfig(
- val id: String,
-
- /** Transition to AOD should move smartspace like large clock instead of small clock */
- val useAlternateSmartspaceAODTransition: Boolean = false,
-
- /** True if the clock will react to tone changes in the seed color. */
- val isReactiveToTone: Boolean = true,
-)
-
-/** Render configuration options for a clock face. Modifies the way SystemUI behaves. */
-data class ClockFaceConfig(
- /** Expected interval between calls to onTimeTick. Can always reduce to PER_MINUTE in AOD. */
- val tickRate: ClockTickRate = ClockTickRate.PER_MINUTE,
-
- /** Call to check whether the clock consumes weather data */
- val hasCustomWeatherDataDisplay: Boolean = false,
-
- /**
- * Whether this clock has a custom position update animation. If true, the keyguard will call
- * `onPositionUpdated` to notify the clock of a position update animation. If false, a default
- * animation will be used (e.g. a simple translation).
- */
- val hasCustomPositionUpdatedAnimation: Boolean = false,
-)
-
-/** Structure for keeping clock-specific settings */
-@Keep
-data class ClockSettings(
- val clockId: ClockId? = null,
- val seedColor: Int? = null,
-) {
- // Exclude metadata from equality checks
- var metadata: JSONObject = JSONObject()
-
- companion object {
- private val KEY_CLOCK_ID = "clockId"
- private val KEY_SEED_COLOR = "seedColor"
- private val KEY_METADATA = "metadata"
-
- fun serialize(setting: ClockSettings?): String {
- if (setting == null) {
- return ""
- }
-
- return JSONObject()
- .put(KEY_CLOCK_ID, setting.clockId)
- .put(KEY_SEED_COLOR, setting.seedColor)
- .put(KEY_METADATA, setting.metadata)
- .toString()
- }
-
- fun deserialize(jsonStr: String?): ClockSettings? {
- if (jsonStr.isNullOrEmpty()) {
- return null
- }
-
- val json = JSONObject(jsonStr)
- val result =
- ClockSettings(
- if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null,
- if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
- )
- if (!json.isNull(KEY_METADATA)) {
- result.metadata = json.getJSONObject(KEY_METADATA)
- }
- return result
- }
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/DarkIconDispatcher.java b/systemUIPlugin/src/com/android/systemui/plugins/DarkIconDispatcher.java
deleted file mode 100644
index a5e5aaa499..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/DarkIconDispatcher.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area and dark
- * intensity. Accessible through {@link PluginDependency}
- */
-@ProvidesInterface(version = DarkIconDispatcher.VERSION)
-@DependsOn(target = DarkReceiver.class)
-public interface DarkIconDispatcher {
- int VERSION = 2;
-
- /**
- * Sets the dark area so {@link #applyDark} only affects the icons in the specified area.
- *
- * @param r the areas in which icons should change its tint, in logical screen
- * coordinates
- */
- void setIconsDarkArea(ArrayList r);
-
- /**
- * Adds a receiver to receive callbacks onDarkChanged
- */
- void addDarkReceiver(DarkReceiver receiver);
-
- /**
- * Adds a receiver to receive callbacks onDarkChanged
- */
- void addDarkReceiver(ImageView imageView);
-
- /**
- * Must have been previously been added through one of the addDarkReceive methods above.
- */
- void removeDarkReceiver(DarkReceiver object);
-
- /**
- * Must have been previously been added through one of the addDarkReceive methods above.
- */
- void removeDarkReceiver(ImageView object);
-
- /**
- * Used to reapply darkness on an object, must have previously been added through
- * addDarkReceiver.
- */
- void applyDark(DarkReceiver object);
-
- int DEFAULT_ICON_TINT = Color.WHITE;
- Rect sTmpRect = new Rect();
- int[] sTmpInt2 = new int[2];
-
- /**
- * @return the tint to apply to view depending on the desired tint color and
- * the screen tintArea in which to apply that tint
- */
- static int getTint(Collection tintAreas, View view, int color) {
- if (isInAreas(tintAreas, view)) {
- return color;
- } else {
- return DEFAULT_ICON_TINT;
- }
- }
-
- /**
- * @return true if more than half of the view area are in any of the given
- * areas, false otherwise
- */
- static boolean isInAreas(Collection areas, View view) {
- if (areas.isEmpty()) {
- return true;
- }
- for (Rect area : areas) {
- if (isInArea(area, view)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * @return true if more than half of the view area are in area, false
- * otherwise
- */
- static boolean isInArea(Rect area, View view) {
- if (area.isEmpty()) {
- return true;
- }
- sTmpRect.set(area);
- view.getLocationOnScreen(sTmpInt2);
- int left = sTmpInt2[0];
-
- int intersectStart = Math.max(left, area.left);
- int intersectEnd = Math.min(left + view.getWidth(), area.right);
- int intersectAmount = Math.max(0, intersectEnd - intersectStart);
-
- boolean coversFullStatusBar = area.top <= 0;
- boolean majorityOfWidth = 2 * intersectAmount > view.getWidth();
- return majorityOfWidth && coversFullStatusBar;
- }
-
- /**
- * Receives a callback on darkness changes
- */
- @ProvidesInterface(version = DarkReceiver.VERSION)
- interface DarkReceiver {
- int VERSION = 2;
- void onDarkChanged(ArrayList areas, float darkIntensity, int tint);
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/DozeServicePlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/DozeServicePlugin.java
deleted file mode 100644
index 3ca5690af4..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/DozeServicePlugin.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.android.systemui.plugins;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-@ProvidesInterface(action = DozeServicePlugin.ACTION, version = DozeServicePlugin.VERSION)
-public interface DozeServicePlugin extends Plugin {
- String ACTION = "com.android.systemui.action.PLUGIN_DOZE";
- int VERSION = 1;
-
- public interface RequestDoze {
- void onRequestShowDoze();
-
- void onRequestHideDoze();
- }
-
- void onDreamingStarted();
-
- void onDreamingStopped();
-
- void setDozeRequester(RequestDoze requester);
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/FalsingManager.java b/systemUIPlugin/src/com/android/systemui/plugins/FalsingManager.java
deleted file mode 100644
index e52a57f761..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/FalsingManager.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.annotation.IntDef;
-import android.net.Uri;
-import android.view.MotionEvent;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Interface that decides whether a touch on the phone was accidental. i.e. Pocket Dialing.
- *
- * {@see com.android.systemui.classifier.BrightLineFalsingManager}
- */
-@ProvidesInterface(version = FalsingManager.VERSION)
-public interface FalsingManager {
- int VERSION = 6;
-
- int NO_PENALTY = 0;
- int LOW_PENALTY = 1;
- int MODERATE_PENALTY = 2;
- int HIGH_PENALTY = 3;
-
- @IntDef({
- NO_PENALTY,
- LOW_PENALTY,
- MODERATE_PENALTY,
- HIGH_PENALTY
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Penalty {}
-
- void onSuccessfulUnlock();
-
- boolean isUnlockingDisabled();
-
- /** Returns true if the gesture should be rejected. */
- boolean isFalseTouch(int interactionType);
-
- /**
- * Does basic checking to see if gesture looks like a tap.
- *
- * Only does the most basic of checks. No penalty is applied if this method returns false.
- *
- * For more robust analysis, use {@link #isFalseTap(int)}.
- */
- boolean isSimpleTap();
-
- /**
- * Returns true if the FalsingManager thinks the last gesture was not a valid tap.
- *
- * This method runs a more thorough analysis than the similar {@link #isSimpleTap()},
- * that can include historical interactions and other contextual cues to see
- * if the tap looks accidental.
- *
- * Use this method to validate a tap for launching an action, like opening
- * a notification.
- *
- * The only parameter, penalty, indicates how much this should affect future gesture
- * classifications if this tap looks like a false. As single taps are hard to confirm as false
- * or otherwise, a low penalty value is encouraged unless context indicates otherwise.
- */
- boolean isFalseTap(@Penalty int penalty);
-
- /**
- * Returns true if the FalsingManager thinks the last gesture was not a valid long tap.
- *
- * Use this method to validate a long tap for launching an action, like long press on a UMO
- *
- * The only parameter, penalty, indicates how much this should affect future gesture
- * classifications if this long tap looks like a false.
- * As long taps are hard to confirm as false or otherwise,
- * a low penalty value is encouraged unless context indicates otherwise.
- */
- boolean isFalseLongTap(@Penalty int penalty);
-
- /**
- * Returns true if the last two gestures do not look like a double tap.
- *
- * Only works on data that has already been reported to the FalsingManager. Be sure that
- * {@link com.android.systemui.classifier.FalsingCollector#onTouchEvent(MotionEvent)}
- * has already been called for all of the taps you want considered.
- *
- * This looks at the last two gestures on the screen, ensuring that they meet the following
- * criteria:
- *
- * a) There are at least two gestures.
- * b) The last two gestures look like taps.
- * c) The last two gestures look like a double tap taken together.
- *
- * This method is _not_ context aware. That is to say, if two taps occur on two neighboring
- * views, but are otherwise close to one another, this will report a successful double tap.
- * It is up to the caller to decide
- * @return
- */
- boolean isFalseDoubleTap();
-
- /**
- * Whether the last proximity event reported NEAR. May be used to short circuit motion events
- * that require the proximity sensor is not covered.
- */
- boolean isProximityNear();
-
- boolean isClassifierEnabled();
-
- boolean shouldEnforceBouncer();
-
- Uri reportRejectedTouch();
-
- boolean isReportingEnabled();
-
- /** From com.android.systemui.Dumpable. */
- void dump(PrintWriter pw, String[] args);
-
- /**
- * Don't call this. It's meant for internal use to allow switching between implementations.
- *
- * Tests may also call it.
- **/
- void cleanupInternal();
-
- /** Call to report a ProximityEvent to the FalsingManager. */
- void onProximityEvent(ProximityEvent proximityEvent);
-
- /** Adds a {@link FalsingBeliefListener}. */
- void addFalsingBeliefListener(FalsingBeliefListener listener);
-
- /** Removes a {@link FalsingBeliefListener}. */
- void removeFalsingBeliefListener(FalsingBeliefListener listener);
-
- /** Adds a {@link FalsingTapListener}. */
- void addTapListener(FalsingTapListener falsingTapListener);
-
- /** Removes a {@link FalsingTapListener}. */
- void removeTapListener(FalsingTapListener falsingTapListener);
-
- /** Listener that is alerted when falsing belief level crosses a predfined threshold. */
- interface FalsingBeliefListener {
- void onFalse();
- }
-
- /**
- * Listener that is alerted when an additional tap is required to confirm a single tap.
- **/
- interface FalsingTapListener {
- void onAdditionalTapRequired();
- }
-
- /** Passed to {@link FalsingManager#onProximityEvent}. */
- interface ProximityEvent {
- /** Returns true when the proximity sensor was covered. */
- boolean getCovered();
-
- /** Returns when the proximity sensor was covered in nanoseconds. */
- long getTimestampNs();
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/FalsingPlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/FalsingPlugin.java
deleted file mode 100644
index 53d708d3b2..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/FalsingPlugin.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.content.Context;
-
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Used to capture Falsing data (related to unlocking the screen).
- *
- * The intent is that the data can later be analyzed to validate the quality of the
- * {@link FalsingManager}.
- */
-@ProvidesInterface(action = FalsingPlugin.ACTION, version = FalsingPlugin.VERSION)
-@DependsOn(target = FalsingManager.class)
-public interface FalsingPlugin extends Plugin {
- String ACTION = "com.android.systemui.action.FALSING_PLUGIN";
- int VERSION = 2;
-
- /**
- * Called when there is data to be recorded.
- *
- * @param success Indicates whether the action is considered a success.
- * @param data The raw data to be recorded for analysis.
- */
- default void dataCollected(boolean success, byte[] data) { }
-
- /**
- * Return a {@link FalsingManager} to be used in place of the system's default.
- *
- * @param context
- */
- default FalsingManager getFalsingManager(Context context) {
- return null;
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/FragmentBase.java b/systemUIPlugin/src/com/android/systemui/plugins/FragmentBase.java
deleted file mode 100644
index af55e8b830..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/FragmentBase.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.content.Context;
-import android.view.View;
-
-/**
- * Interface to deal with lack of multiple inheritance
- *
- * This interface is designed to be used as a base class for plugin interfaces
- * that need fragment methods. Plugins should not extend Fragment directly, so
- * plugins that are fragments should be extending PluginFragment, but in SysUI
- * these same versions should extend Fragment directly.
- *
- * Only methods that are on Fragment should be included here.
- */
-public interface FragmentBase {
- View getView();
- Context getContext();
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/GlobalActions.java b/systemUIPlugin/src/com/android/systemui/plugins/GlobalActions.java
deleted file mode 100644
index 95ff13b45f..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/GlobalActions.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-@ProvidesInterface(action = GlobalActions.ACTION, version = GlobalActions.VERSION)
-@DependsOn(target = GlobalActionsManager.class)
-public interface GlobalActions extends Plugin {
-
- String ACTION = "com.android.systemui.action.PLUGIN_GLOBAL_ACTIONS";
- int VERSION = 1;
-
- void showGlobalActions(GlobalActionsManager manager);
- default void showShutdownUi(boolean isReboot, String reason) {
- }
-
- default void destroy() {
- }
-
- @ProvidesInterface(version = GlobalActionsManager.VERSION)
- public interface GlobalActionsManager {
- int VERSION = 1;
-
- void onGlobalActionsShown();
- void onGlobalActionsHidden();
-
- void shutdown();
- void reboot(boolean safeMode);
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
deleted file mode 100644
index 429458fe07..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.annotation.Nullable;
-import android.app.BroadcastOptions;
-import android.app.PendingIntent;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Plugin which provides a "Panel" {@link View} to be rendered inside of the GlobalActions menu.
- *
- * Implementations should construct a new {@link PanelViewController} with the given
- * {@link Callbacks} instance inside of {@link #onPanelShown(Callbacks, boolean)}, and should not
- * hold onto a reference, instead allowing Global Actions to manage the lifetime of the object.
- *
- * Under this assumption, {@link PanelViewController} represents the lifetime of a single invocation
- * of the Global Actions menu. The {@link View} for the Panel is generated when the
- * {@link PanelViewController} is constructed, and {@link PanelViewController#getPanelContent()}
- * serves as a simple getter. When Global Actions is dismissed,
- * {@link PanelViewController#onDismissed()} can be used to cleanup any resources allocated when
- * constructed. Global Actions will then release the reference, and the {@link PanelViewController}
- * will be garbage-collected.
- */
-@ProvidesInterface(
- action = GlobalActionsPanelPlugin.ACTION, version = GlobalActionsPanelPlugin.VERSION)
-@DependsOn(target = GlobalActionsPanelPlugin.Callbacks.class)
-@DependsOn(target = GlobalActionsPanelPlugin.PanelViewController.class)
-public interface GlobalActionsPanelPlugin extends Plugin {
- String ACTION = "com.android.systemui.action.PLUGIN_GLOBAL_ACTIONS_PANEL";
- int VERSION = 0;
-
- /**
- * Invoked when the GlobalActions menu is shown.
- *
- * @param callbacks {@link Callbacks} instance that can be used by the Panel to interact with
- * the Global Actions menu.
- * @param deviceLocked Indicates whether or not the device is currently locked.
- * @return A {@link PanelViewController} instance used to receive Global Actions events.
- */
- PanelViewController onPanelShown(Callbacks callbacks, boolean deviceLocked);
-
- /**
- * Provides methods to interact with the Global Actions menu.
- */
- @ProvidesInterface(version = Callbacks.VERSION)
- interface Callbacks {
- int VERSION = 0;
-
- /** Dismisses the Global Actions menu. */
- void dismissGlobalActionsMenu();
-
- /** Starts a PendingIntent, dismissing the keyguard if necessary. */
- default void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent) {
- try {
- BroadcastOptions options = BroadcastOptions.makeBasic();
- options.setInteractive(true);
- pendingIntent.send(options.toBundle());
- } catch (PendingIntent.CanceledException e) {
- // no-op
- }
- }
- }
-
- /**
- * Receives Global Actions events, and provides the Panel {@link View}.
- */
- @ProvidesInterface(version = PanelViewController.VERSION)
- interface PanelViewController {
- int VERSION = 0;
-
- /**
- * Returns the {@link View} for the Panel to be rendered in Global Actions. This View can be
- * any size, and will be rendered above the Global Actions menu when z-ordered.
- */
- View getPanelContent();
-
- /**
- * Invoked when the Global Actions menu (containing the View returned from
- * {@link #getPanelContent()}) is dismissed.
- */
- void onDismissed();
-
- /**
- * Invoked when the device is either locked or unlocked.
- */
- void onDeviceLockStateChanged(boolean locked);
-
- /**
- * Optionally returns a drawable to be used as the background for Global Actions.
- */
- @Nullable
- default Drawable getBackgroundDrawable() {
- return null;
- }
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/IntentButtonProvider.java b/systemUIPlugin/src/com/android/systemui/plugins/IntentButtonProvider.java
deleted file mode 100644
index 97dbafd65d..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/IntentButtonProvider.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-
-/**
- * An Intent Button represents a triggerable element in SysUI that consists of an
- * Icon and an intent to trigger when it is activated (clicked, swiped, etc.).
- */
-@ProvidesInterface(version = IntentButtonProvider.VERSION)
-public interface IntentButtonProvider extends Plugin {
-
- public static final int VERSION = 1;
-
- public IntentButton getIntentButton();
-
- public interface IntentButton {
- public static class IconState {
- public boolean isVisible = true;
- public CharSequence contentDescription = null;
- public Drawable drawable;
- public boolean tint = true;
- }
-
- public IconState getIcon();
-
- public Intent getIntent();
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
deleted file mode 100644
index 5f6f11c16d..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.graphics.Point;
-import android.view.MotionEvent;
-import android.view.WindowManager;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-import java.io.PrintWriter;
-
-/** Plugin to handle navigation edge gestures for Back. */
-@ProvidesInterface(
- action = NavigationEdgeBackPlugin.ACTION,
- version = NavigationEdgeBackPlugin.VERSION)
-public interface NavigationEdgeBackPlugin extends Plugin {
- String ACTION = "com.android.systemui.action.PLUGIN_NAVIGATION_EDGE_BACK_ACTION";
- int VERSION = 1;
-
-
- /** Specifies if the UI should be rendered on the left side of the screen. */
- void setIsLeftPanel(boolean isLeftPanel);
-
- /** Sets the insets for the gesture handling area. */
- void setInsets(int leftInset, int rightInset);
-
- /** Sets the display size. */
- void setDisplaySize(Point displaySize);
-
- /** Sets the callback that should be invoked when a Back gesture is detected. */
- void setBackCallback(BackCallback callback);
-
- /** Sets the base LayoutParams for the UI. */
- void setLayoutParams(WindowManager.LayoutParams layoutParams);
-
- /** Updates the UI based on the motion events passed in device coordinates. */
- void onMotionEvent(MotionEvent motionEvent);
-
- /** Dumps info about the back gesture plugin. */
- void dump(PrintWriter pw);
-
- /** Callback to let the system react to the detected back gestures. */
- interface BackCallback {
- /** Indicates that a Back gesture was recognized and the system should go back. */
- void triggerBack();
-
- /** Indicates that the gesture was cancelled and the system should not go back. */
- void cancelBack();
-
- /**
- * Indicates if back will be triggered if committed in current state.
- *
- * @param triggerBack if back will be triggered in current state.
- */
- void setTriggerBack(boolean triggerBack);
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/NotificationListenerController.java b/systemUIPlugin/src/com/android/systemui/plugins/NotificationListenerController.java
deleted file mode 100644
index 6799450079..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/NotificationListenerController.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.app.NotificationChannel;
-import android.os.UserHandle;
-import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.StatusBarNotification;
-
-import com.android.systemui.plugins.NotificationListenerController.NotificationProvider;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-@ProvidesInterface(action = NotificationListenerController.ACTION,
- version = NotificationListenerController.VERSION)
-@DependsOn(target = NotificationProvider.class)
-public interface NotificationListenerController extends Plugin {
- String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_ASSISTANT";
- int VERSION = 1;
-
- void onListenerConnected(NotificationProvider provider);
-
- /**
- * @return whether plugin wants to skip the default callbacks.
- */
- default boolean onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
- return false;
- }
-
- /**
- * @return whether plugin wants to skip the default callbacks.
- */
- default boolean onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
- return false;
- }
-
- /**
- * Called when a notification channel is modified.
- * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
- * {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
- * {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
- * @return whether a plugin wants to skip the default callbacks.
- */
- default boolean onNotificationChannelModified(
- String pkgName, UserHandle user, NotificationChannel channel, int modificationType) {
- return false;
- }
-
- default StatusBarNotification[] getActiveNotifications(
- StatusBarNotification[] activeNotifications) {
- return activeNotifications;
- }
-
- default RankingMap getCurrentRanking(RankingMap currentRanking) {
- return currentRanking;
- }
-
- @ProvidesInterface(version = NotificationProvider.VERSION)
- interface NotificationProvider {
- int VERSION = 1;
-
- // Methods to get info about current notifications
- StatusBarNotification[] getActiveNotifications();
- RankingMap getRankingMap();
-
- // Methods to notify sysui of changes to notification list.
- void addNotification(StatusBarNotification sbn);
- void removeNotification(StatusBarNotification sbn);
- void updateRanking();
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/NotificationPersonExtractorPlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/NotificationPersonExtractorPlugin.java
deleted file mode 100644
index f79cd8625c..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/NotificationPersonExtractorPlugin.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.graphics.drawable.Drawable;
-import android.service.notification.StatusBarNotification;
-
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/** Custom logic that can extract a PeopleHub "person" from a notification. */
-@ProvidesInterface(
- action = NotificationPersonExtractorPlugin.ACTION,
- version = NotificationPersonExtractorPlugin.VERSION)
-@DependsOn(target = NotificationPersonExtractorPlugin.PersonData.class)
-public interface NotificationPersonExtractorPlugin extends Plugin {
-
- String ACTION = "com.android.systemui.action.PEOPLE_HUB_PERSON_EXTRACTOR";
- int VERSION = 1;
-
- /**
- * Attempts to extract a person from a notification. Returns {@code null} if one is not found.
- */
- @Nullable
- PersonData extractPerson(StatusBarNotification sbn);
-
- /**
- * Attempts to extract a person id from a notification. Returns {@code null} if one is not
- * found.
- *
- * This method can be overridden in order to provide a faster implementation.
- */
- @Nullable
- default String extractPersonKey(StatusBarNotification sbn) {
- return extractPerson(sbn).key;
- }
-
- /**
- * Determines whether or not a notification should be treated as having a person. Used for
- * appropriate positioning in the notification shade.
- */
- default boolean isPersonNotification(StatusBarNotification sbn) {
- return extractPersonKey(sbn) != null;
- }
-
- /** A person to be surfaced in PeopleHub. */
- @ProvidesInterface(version = PersonData.VERSION)
- final class PersonData {
-
- public static final int VERSION = 0;
-
- public final String key;
- public final CharSequence name;
- public final Drawable avatar;
- public final Runnable clickRunnable;
-
- public PersonData(String key, CharSequence name, Drawable avatar,
- Runnable clickRunnable) {
- this.key = key;
- this.name = name;
- this.avatar = avatar;
- this.clickRunnable = clickRunnable;
- }
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/OverlayPlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/OverlayPlugin.java
deleted file mode 100644
index 075df75f93..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/OverlayPlugin.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.android.systemui.plugins;
-
-import android.view.View;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.statusbar.DozeParameters;
-
-@ProvidesInterface(action = OverlayPlugin.ACTION, version = OverlayPlugin.VERSION)
-public interface OverlayPlugin extends Plugin {
-
- String ACTION = "com.android.systemui.action.PLUGIN_OVERLAY";
- int VERSION = 4;
-
- /**
- * Setup overlay plugin
- */
- void setup(View statusBar, View navBar);
-
- /**
- * Setup overlay plugin with callback and DozeParameters
- */
- default void setup(View statusBar, View navBar, Callback callback,
- DozeParameters dozeParameters) {
- setup(statusBar, navBar);
- }
-
- default boolean holdStatusBarOpen() {
- return false;
- }
-
- /**
- * Only called if the plugin has returned true to holdStatusBarOpen().
- */
- default void setCollapseDesired(boolean collapseDesired) {
- }
-
- /**
- * Used to update system ui whether to hold status bar open
- */
- interface Callback {
- void onHoldStatusBarOpenChange();
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/PluginDependency.java b/systemUIPlugin/src/com/android/systemui/plugins/PluginDependency.java
deleted file mode 100644
index 25ce3ddf81..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/PluginDependency.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-@ProvidesInterface(version = PluginDependency.VERSION)
-public class PluginDependency {
- public static final int VERSION = 1;
- static DependencyProvider sProvider;
-
- public static T get(Plugin p, Class cls) {
- return sProvider.get(p, cls);
- }
-
- static abstract class DependencyProvider {
- abstract T get(Plugin p, Class cls);
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/PluginUtils.java b/systemUIPlugin/src/com/android/systemui/plugins/PluginUtils.java
deleted file mode 100644
index af49d43c97..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/PluginUtils.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-
-public class PluginUtils {
-
- public static void setId(Context sysuiContext, View view, String id) {
- int i = sysuiContext.getResources().getIdentifier(id, "id", sysuiContext.getPackageName());
- view.setId(i);
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/SensorManagerPlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
deleted file mode 100644
index d62c1d411c..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.hardware.SensorListener;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Allows for additional sensors to be retrieved from
- * {@link com.android.systemui.util.sensors.AsyncSensorManager}.
- */
-@ProvidesInterface(action = SensorManagerPlugin.ACTION, version = SensorManagerPlugin.VERSION)
-public interface SensorManagerPlugin extends Plugin {
- String ACTION = "com.android.systemui.action.PLUGIN_SENSOR_MANAGER";
- int VERSION = 1;
-
- /**
- * Registers for sensor events. Events will be sent until the listener is unregistered.
- * @param sensor
- * @param listener
- * @see android.hardware.SensorManager#registerListener(SensorListener, int)
- */
- void registerListener(Sensor sensor, SensorEventListener listener);
-
- /**
- * Unregisters events from the sensor.
- * @param sensor
- * @param listener
- */
- void unregisterListener(Sensor sensor, SensorEventListener listener);
-
- /**
- * Listener triggered whenever the Sensor has new data.
- */
- interface SensorEventListener {
- void onSensorChanged(SensorEvent event);
- }
-
- /**
- * Sensor that can be defined in a plugin.
- */
- class Sensor {
- public static final int TYPE_WAKE_LOCK_SCREEN = 1;
- public static final int TYPE_WAKE_DISPLAY = 2;
- public static final int TYPE_SWIPE = 3;
- public static final int TYPE_SKIP_STATUS = 4;
-
- private int mType;
-
- public Sensor(int type) {
- mType = type;
- }
- public int getType() {
- return mType;
- }
- public String toString() {
- return "{PluginSensor type=\"" + mType + "\"}";
- }
- }
-
- /**
- * Event sent by a {@link Sensor}.
- */
- class SensorEvent {
- Sensor mSensor;
- int mVendorType;
- float[] mValues;
-
- /**
- * Creates a sensor event.
- * @param sensor The type of sensor, e.g. TYPE_WAKE_LOCK_SCREEN
- * @param vendorType The vendor type, which should be unique for each type of sensor,
- * e.g. SINGLE_TAP = 1, DOUBLE_TAP = 2, etc.
- */
- public SensorEvent(Sensor sensor, int vendorType) {
- this(sensor, vendorType, null);
- }
-
- /**
- * Creates a sensor event.
- * @param sensor The type of sensor, e.g. TYPE_WAKE_LOCK_SCREEN
- * @param vendorType The vendor type, which should be unique for each type of sensor,
- * e.g. SINGLE_TAP = 1, DOUBLE_TAP = 2, etc.
- * @param values Values captured by the sensor.
- */
- public SensorEvent(Sensor sensor, int vendorType, float[] values) {
- mSensor = sensor;
- mVendorType = vendorType;
- mValues = values;
- }
-
- public Sensor getSensor() {
- return mSensor;
- }
-
- public float[] getValues() {
- return mValues;
- }
-
- public int getVendorType() {
- return mVendorType;
- }
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/ToastPlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/ToastPlugin.java
deleted file mode 100644
index da079cf044..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/ToastPlugin.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.animation.Animator;
-import android.annotation.NonNull;
-import android.view.View;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Customize toasts displayed by SystemUI (via Toast#makeText)
- */
-@ProvidesInterface(action = ToastPlugin.ACTION, version = ToastPlugin.VERSION)
-public interface ToastPlugin extends Plugin {
-
- String ACTION = "com.android.systemui.action.PLUGIN_TOAST";
- int VERSION = 1;
-
- /**
- * Creates a CustomPluginToast.
- */
- @NonNull Toast createToast(CharSequence text, String packageName, int userId);
-
- /**
- * Custom Toast with the ability to change toast positioning, styling and animations.
- */
- interface Toast {
- /**
- * Retrieve the Toast view's gravity.
- * If no changes, returns null.
- */
- default Integer getGravity() {
- return null;
- }
-
- /**
- * Retrieve the Toast view's X-offset.
- * If no changes, returns null.
- */
- default Integer getXOffset() {
- return null;
- }
-
- /**
- * Retrieve the Toast view's Y-offset.
- * If no changes, returns null.
- */
- default Integer getYOffset() {
- return null;
- }
-
- /**
- * Retrieve the Toast view's horizontal margin.
- * If no changes, returns null.
- */
- default Integer getHorizontalMargin() {
- return null;
- }
-
- /**
- * Retrieve the Toast view's vertical margin.
- * If no changes, returns null.
- */
- default Integer getVerticalMargin() {
- return null;
- }
-
- /**
- * Retrieve the Toast view to show.
- * If no changes, returns null.
- */
- default View getView() {
- return null;
- }
-
- /**
- * Retrieve the Toast's animate in.
- * If no changes, returns null.
- */
- default Animator getInAnimation() {
- return null;
- }
-
- /**
- * Retrieve the Toast's animate out.
- * If no changes, returns null.
- */
- default Animator getOutAnimation() {
- return null;
- }
-
- /**
- * Called on orientation changes.
- */
- default void onOrientationChange(int orientation) { }
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/ViewProvider.java b/systemUIPlugin/src/com/android/systemui/plugins/ViewProvider.java
deleted file mode 100644
index 18ca8e6e26..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/ViewProvider.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.view.View;
-
-public interface ViewProvider extends Plugin {
- View getView();
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/VolumeDialog.java b/systemUIPlugin/src/com/android/systemui/plugins/VolumeDialog.java
deleted file mode 100644
index 9e5db73cf8..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/VolumeDialog.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import com.android.systemui.plugins.VolumeDialog.Callback;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * This interface is really just a stub for initialization/teardown, actual handling of
- * when to show will be done through {@link VolumeDialogController}
- */
-@ProvidesInterface(action = VolumeDialog.ACTION, version = VolumeDialog.VERSION)
-@DependsOn(target = Callback.class)
-public interface VolumeDialog extends Plugin {
- String ACTION = "com.android.systemui.action.PLUGIN_VOLUME";
- int VERSION = 1;
-
- void init(int windowType, Callback callback);
- void destroy();
-
- @ProvidesInterface(version = VERSION)
- public interface Callback {
- int VERSION = 1;
-
- void onZenSettingsClicked();
- void onZenPrioritySettingsClicked();
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/VolumeDialogController.java b/systemUIPlugin/src/com/android/systemui/plugins/VolumeDialogController.java
deleted file mode 100644
index 3d9645a3d9..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/VolumeDialogController.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.annotation.IntegerRes;
-import android.content.ComponentName;
-import android.media.AudioManager;
-import android.media.AudioSystem;
-import android.os.Handler;
-import android.os.VibrationEffect;
-import android.util.SparseArray;
-
-import com.android.systemui.plugins.VolumeDialogController.Callbacks;
-import com.android.systemui.plugins.VolumeDialogController.State;
-import com.android.systemui.plugins.VolumeDialogController.StreamState;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Manages the VolumeDialog.
- *
- * Accessible through {@link PluginDependency}
- */
-@ProvidesInterface(version = VolumeDialogController.VERSION)
-@DependsOn(target = StreamState.class)
-@DependsOn(target = State.class)
-@DependsOn(target = Callbacks.class)
-public interface VolumeDialogController {
- int VERSION = 1;
-
- void setActiveStream(int stream);
- void setStreamVolume(int stream, int userLevel);
- void setRingerMode(int ringerModeNormal, boolean external);
-
- boolean hasVibrator();
- void vibrate(VibrationEffect effect);
- void scheduleTouchFeedback();
-
- AudioManager getAudioManager();
-
- void notifyVisible(boolean visible);
-
- void addCallback(Callbacks callbacks, Handler handler);
- void removeCallback(Callbacks callbacks);
-
- void userActivity();
- void getState();
-
- /**
- * Get Captions enabled state
- *
- * @param checkForSwitchState set true when we'd like to switch captions enabled state after
- * getting the latest captions state.
- */
- void getCaptionsEnabledState(boolean checkForSwitchState);
-
- /**
- * Set Captions enabled state
- *
- * @param enabled the captions enabled state we'd like to update.
- */
- void setCaptionsEnabledState(boolean enabled);
-
- /**
- * Get Captions component state
- *
- * @param fromTooltip if it's triggered from tooltip.
- */
- void getCaptionsComponentState(boolean fromTooltip);
-
- @ProvidesInterface(version = StreamState.VERSION)
- public static final class StreamState {
- public static final int VERSION = 1;
-
- public boolean dynamic;
- public int level;
- public int levelMin;
- public int levelMax;
- public boolean muted;
- public boolean muteSupported;
- public @IntegerRes int name;
- public String remoteLabel;
- public boolean routedToBluetooth;
-
- public StreamState copy() {
- final StreamState rt = new StreamState();
- rt.dynamic = dynamic;
- rt.level = level;
- rt.levelMin = levelMin;
- rt.levelMax = levelMax;
- rt.muted = muted;
- rt.muteSupported = muteSupported;
- rt.name = name;
- rt.remoteLabel = remoteLabel;
- rt.routedToBluetooth = routedToBluetooth;
- return rt;
- }
- }
-
- @ProvidesInterface(version = State.VERSION)
- public static final class State {
- public static final int VERSION = 1;
-
- public static int NO_ACTIVE_STREAM = -1;
-
- public final SparseArray states = new SparseArray<>();
-
- public int ringerModeInternal;
- public int ringerModeExternal;
- public int zenMode;
- public ComponentName effectsSuppressor;
- public String effectsSuppressorName;
- public int activeStream = NO_ACTIVE_STREAM;
- public boolean disallowAlarms;
- public boolean disallowMedia;
- public boolean disallowSystem;
- public boolean disallowRinger;
-
- public State copy() {
- final State rt = new State();
- for (int i = 0; i < states.size(); i++) {
- rt.states.put(states.keyAt(i), states.valueAt(i).copy());
- }
- rt.ringerModeExternal = ringerModeExternal;
- rt.ringerModeInternal = ringerModeInternal;
- rt.zenMode = zenMode;
- if (effectsSuppressor != null) {
- rt.effectsSuppressor = effectsSuppressor.clone();
- }
- rt.effectsSuppressorName = effectsSuppressorName;
- rt.activeStream = activeStream;
- rt.disallowAlarms = disallowAlarms;
- rt.disallowMedia = disallowMedia;
- rt.disallowSystem = disallowSystem;
- rt.disallowRinger = disallowRinger;
- return rt;
- }
-
- @Override
- public String toString() {
- return toString(0);
- }
-
- public String toString(int indent) {
- final StringBuilder sb = new StringBuilder("{");
- if (indent > 0) sep(sb, indent);
- for (int i = 0; i < states.size(); i++) {
- if (i > 0) {
- sep(sb, indent);
- }
- final int stream = states.keyAt(i);
- final StreamState ss = states.valueAt(i);
- sb.append(AudioSystem.streamToString(stream)).append(":").append(ss.level)
- .append('[').append(ss.levelMin).append("..").append(ss.levelMax)
- .append(']');
- if (ss.muted) sb.append(" [MUTED]");
- if (ss.dynamic) sb.append(" [DYNAMIC]");
- }
- sep(sb, indent); sb.append("ringerModeExternal:").append(ringerModeExternal);
- sep(sb, indent); sb.append("ringerModeInternal:").append(ringerModeInternal);
- sep(sb, indent); sb.append("zenMode:").append(zenMode);
- sep(sb, indent); sb.append("effectsSuppressor:").append(effectsSuppressor);
- sep(sb, indent); sb.append("effectsSuppressorName:").append(effectsSuppressorName);
- sep(sb, indent); sb.append("activeStream:").append(activeStream);
- sep(sb, indent); sb.append("disallowAlarms:").append(disallowAlarms);
- sep(sb, indent); sb.append("disallowMedia:").append(disallowMedia);
- sep(sb, indent); sb.append("disallowSystem:").append(disallowSystem);
- sep(sb, indent); sb.append("disallowRinger:").append(disallowRinger);
- if (indent > 0) sep(sb, indent);
- return sb.append('}').toString();
- }
-
- private static void sep(StringBuilder sb, int indent) {
- if (indent > 0) {
- sb.append('\n');
- for (int i = 0; i < indent; i++) {
- sb.append(' ');
- }
- } else {
- sb.append(',');
- }
- }
- }
-
- @ProvidesInterface(version = Callbacks.VERSION)
- public interface Callbacks {
- int VERSION = 2;
-
- // requires version 1
- void onShowRequested(int reason, boolean keyguardLocked, int lockTaskModeState);
- void onDismissRequested(int reason);
- void onStateChanged(State state);
- void onLayoutDirectionChanged(int layoutDirection);
- void onConfigurationChanged();
- void onShowVibrateHint();
- void onShowSilentHint();
- void onScreenOff();
- void onShowSafetyWarning(int flags);
- void onAccessibilityModeChanged(Boolean showA11yStream);
-
- /**
- * Callback function for captions component state changed event
- *
- * @param isComponentEnabled the lateset captions component state.
- * @param fromTooltip if it's triggered from tooltip.
- */
- void onCaptionComponentStateChanged(Boolean isComponentEnabled, Boolean fromTooltip);
-
- /**
- * Callback function for captions enabled state changed event
- *
- * @param isEnabled the lateset captions enabled state.
- * @param checkBeforeSwitch intend to switch captions enabled state after the callback.
- */
- void onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkBeforeSwitch);
- // requires version 2
- void onShowCsdWarning(@AudioManager.CsdWarning int csdWarning, int durationMs);
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/WeatherData.kt b/systemUIPlugin/src/com/android/systemui/plugins/WeatherData.kt
deleted file mode 100644
index affb76b79d..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/WeatherData.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.android.systemui.plugins
-
-import android.os.Bundle
-import android.util.Log
-import android.view.View
-import androidx.annotation.VisibleForTesting
-
-typealias WeatherTouchAction = (View) -> Unit
-
-class WeatherData
-constructor(
- val description: String,
- val state: WeatherStateIcon,
- val useCelsius: Boolean,
- val temperature: Int,
- val touchAction: WeatherTouchAction? = null,
-) {
- companion object {
- const val DEBUG = true
- private const val TAG = "WeatherData"
- @VisibleForTesting const val DESCRIPTION_KEY = "description"
- @VisibleForTesting const val STATE_KEY = "state"
- @VisibleForTesting const val USE_CELSIUS_KEY = "use_celsius"
- @VisibleForTesting const val TEMPERATURE_KEY = "temperature"
- private const val INVALID_WEATHER_ICON_STATE = -1
-
- fun fromBundle(extras: Bundle, touchAction: WeatherTouchAction? = null): WeatherData? {
- val description = extras.getString(DESCRIPTION_KEY)
- val state =
- WeatherStateIcon.fromInt(extras.getInt(STATE_KEY, INVALID_WEATHER_ICON_STATE))
- val temperature = readIntFromBundle(extras, TEMPERATURE_KEY)
- if (
- description == null ||
- state == null ||
- !extras.containsKey(USE_CELSIUS_KEY) ||
- temperature == null
- ) {
- if (DEBUG) {
- Log.w(TAG, "Weather data did not parse from $extras")
- }
- return null
- } else {
- val result =
- WeatherData(
- description = description,
- state = state,
- useCelsius = extras.getBoolean(USE_CELSIUS_KEY),
- temperature = temperature,
- touchAction = touchAction
- )
- if (DEBUG) {
- Log.i(TAG, "Weather data parsed $result from $extras")
- }
- return result
- }
- }
-
- private fun readIntFromBundle(extras: Bundle, key: String): Int? =
- try {
- extras.getString(key)?.toInt()
- } catch (e: Exception) {
- null
- }
- }
-
- // Values for WeatherStateIcon must stay in sync with go/g3-WeatherStateIcon
- enum class WeatherStateIcon(val id: Int) {
- UNKNOWN_ICON(0),
-
- // Clear, day & night.
- SUNNY(1),
- CLEAR_NIGHT(2),
-
- // Mostly clear, day & night.
- MOSTLY_SUNNY(3),
- MOSTLY_CLEAR_NIGHT(4),
-
- // Partly cloudy, day & night.
- PARTLY_CLOUDY(5),
- PARTLY_CLOUDY_NIGHT(6),
-
- // Mostly cloudy, day & night.
- MOSTLY_CLOUDY_DAY(7),
- MOSTLY_CLOUDY_NIGHT(8),
- CLOUDY(9),
- HAZE_FOG_DUST_SMOKE(10),
- DRIZZLE(11),
- HEAVY_RAIN(12),
- SHOWERS_RAIN(13),
-
- // Scattered showers, day & night.
- SCATTERED_SHOWERS_DAY(14),
- SCATTERED_SHOWERS_NIGHT(15),
-
- // Isolated scattered thunderstorms, day & night.
- ISOLATED_SCATTERED_TSTORMS_DAY(16),
- ISOLATED_SCATTERED_TSTORMS_NIGHT(17),
- STRONG_TSTORMS(18),
- BLIZZARD(19),
- BLOWING_SNOW(20),
- FLURRIES(21),
- HEAVY_SNOW(22),
-
- // Scattered snow showers, day & night.
- SCATTERED_SNOW_SHOWERS_DAY(23),
- SCATTERED_SNOW_SHOWERS_NIGHT(24),
- SNOW_SHOWERS_SNOW(25),
- MIXED_RAIN_HAIL_RAIN_SLEET(26),
- SLEET_HAIL(27),
- TORNADO(28),
- TROPICAL_STORM_HURRICANE(29),
- WINDY_BREEZY(30),
- WINTRY_MIX_RAIN_SNOW(31);
-
- companion object {
- fun fromInt(value: Int) = values().firstOrNull { it.id == value }
- }
- }
-
- override fun toString(): String {
- val unit = if (useCelsius) "C" else "F"
- return "$state (\"$description\") $temperature°$unit"
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/log/TableLogBufferBase.kt b/systemUIPlugin/src/com/android/systemui/plugins/log/TableLogBufferBase.kt
deleted file mode 100644
index 50b3f78a49..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/log/TableLogBufferBase.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins.log
-
-/**
- * Base interface for a logger that logs changes in table format.
- *
- * This is a plugin interface for classes outside of SystemUI core.
- */
-interface TableLogBufferBase {
- /**
- * Logs a String? change.
- *
- * For Java overloading.
- */
- fun logChange(prefix: String, columnName: String, value: String?) {
- logChange(prefix, columnName, value, isInitial = false)
- }
-
- /** Logs a String? change. */
- fun logChange(prefix: String, columnName: String, value: String?, isInitial: Boolean)
-
- /**
- * Logs a Boolean change.
- *
- * For Java overloading.
- */
- fun logChange(prefix: String, columnName: String, value: Boolean) {
- logChange(prefix, columnName, value, isInitial = false)
- }
-
- /** Logs a Boolean change. */
- fun logChange(prefix: String, columnName: String, value: Boolean, isInitial: Boolean)
-
- /**
- * Logs an Int? change.
- *
- * For Java overloading.
- */
- fun logChange(prefix: String, columnName: String, value: Int?) {
- logChange(prefix, columnName, value, isInitial = false)
- }
-
- /** Logs an Int? change. */
- fun logChange(prefix: String, columnName: String, value: Int?, isInitial: Boolean)
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/qs/QS.java b/systemUIPlugin/src/com/android/systemui/plugins/qs/QS.java
deleted file mode 100644
index 3244eb43c8..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/qs/QS.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins.qs;
-
-import android.view.View;
-
-import androidx.annotation.FloatRange;
-
-import com.android.systemui.plugins.FragmentBase;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.qs.QS.HeightListener;
-
-import java.util.function.Consumer;
-
-/**
- * Fragment that contains QS in the notification shade. Most of the interface is for
- * handling the expand/collapsing of the view interaction.
- */
-@ProvidesInterface(action = QS.ACTION, version = QS.VERSION)
-@DependsOn(target = HeightListener.class)
-public interface QS extends FragmentBase {
-
- String ACTION = "com.android.systemui.action.PLUGIN_QS";
-
- int VERSION = 15;
-
- String TAG = "QS";
-
- void setPanelView(HeightListener notificationPanelView);
-
- void hideImmediately();
- int getQsMinExpansionHeight();
- int getDesiredHeight();
- void setHeightOverride(int desiredHeight);
- void setHeaderClickable(boolean qsExpansionEnabled);
- boolean isCustomizing();
- /** Close the QS customizer, if it is open. */
- void closeCustomizer();
- void setOverscrolling(boolean overscrolling);
- void setExpanded(boolean qsExpanded);
- void setListening(boolean listening);
-
- /**
- * Set whether QQS/QS is visible or not.
- *
- * This is different from setExpanded, as it will be true when QQS is visible. In particular,
- * it should be false when device is locked and only notifications (in lockscreen) are visible.
- */
- void setQsVisible(boolean qsVisible);
- boolean isShowingDetail();
- void closeDetail();
- void animateHeaderSlidingOut();
-
- /**
- * Asks QS to update its presentation, according to {@code NotificationPanelViewController}.
- * @param qsExpansionFraction How much each UI element in QS should be expanded (QQS to QS.)
- * @param panelExpansionFraction Whats the expansion of the whole shade.
- * @param headerTranslation How much we should vertically translate QS.
- * @param squishinessFraction Fraction that affects tile height. 0 when collapsed,
- * 1 when expanded.
- */
- void setQsExpansion(float qsExpansionFraction, float panelExpansionFraction,
- float headerTranslation, float squishinessFraction);
- void setHeaderListening(boolean listening);
- void notifyCustomizeChanged();
- void setContainerController(QSContainerController controller);
-
- /**
- * Provide an action to collapse if expanded or expand if collapsed.
- * @param action
- */
- void setCollapseExpandAction(Runnable action);
-
- /**
- * Returns the height difference between the QSPanel container and the QuickQSPanel container
- */
- int getHeightDiff();
-
- View getHeader();
-
- default void setHasNotifications(boolean hasNotifications) {
- }
-
- /**
- * Should touches from the notification panel be disallowed?
- * The notification panel might grab any touches rom QS at any time to collapse the shade.
- * We should disallow that in case we are showing the detail panel.
- */
- default boolean disallowPanelTouches() {
- return isShowingDetail();
- }
-
- /**
- * If QS should translate as we pull it down, or if it should be static.
- */
- void setInSplitShade(boolean shouldTranslate);
-
- /**
- * Sets the progress of the transition to full shade on the lockscreen.
- *
- * @param isTransitioningToFullShade
- * whether the transition to full shade is in progress. This might be {@code true}, even
- * though {@code qsTransitionFraction} is still 0.
- * The reason for that is that on some device configurations, the QS transition has a
- * start delay compared to the overall transition.
- *
- * @param qsTransitionFraction
- * the fraction of the QS transition progress, from 0 to 1.
- *
- * @param qsSquishinessFraction
- * the fraction of the QS "squish" transition progress, from 0 to 1.
- */
- default void setTransitionToFullShadeProgress(
- boolean isTransitioningToFullShade,
- @FloatRange(from = 0.0, to = 1.0) float qsTransitionFraction,
- @FloatRange(from = 0.0, to = 1.0) float qsSquishinessFraction) {}
-
- /**
- * A rounded corner clipping that makes QS feel as if it were behind everything.
- */
- void setFancyClipping(int leftInset, int top, int rightInset, int bottom, int cornerRadius,
- boolean visible, boolean fullWidth);
-
- /**
- * @return if quick settings is fully collapsed currently
- */
- default boolean isFullyCollapsed() {
- return true;
- }
-
- /**
- * Add a listener for when the collapsed media visibility changes.
- */
- void setCollapsedMediaVisibilityChangedListener(Consumer listener);
-
- /**
- * Set a scroll listener for the QSPanel container
- */
- default void setScrollListener(ScrollListener scrollListener) {}
-
- /**
- * Sets the amount of vertical over scroll that should be performed on QS.
- */
- default void setOverScrollAmount(int overScrollAmount) {}
-
- /**
- * Sets whether the notification panel is using the full width of the screen. Typically true on
- * small screens and false on large screens.
- */
- void setIsNotificationPanelFullWidth(boolean isFullWidth);
-
- /**
- * Callback for when QSPanel container is scrolled
- */
- @ProvidesInterface(version = ScrollListener.VERSION)
- interface ScrollListener {
- int VERSION = 1;
- void onQsPanelScrollChanged(int scrollY);
- }
-
- @ProvidesInterface(version = HeightListener.VERSION)
- interface HeightListener {
- int VERSION = 1;
- void onQsHeightChanged();
- }
-
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSContainerController.kt b/systemUIPlugin/src/com/android/systemui/plugins/qs/QSContainerController.kt
deleted file mode 100644
index 9c7fbe8842..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSContainerController.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.android.systemui.plugins.qs
-
-interface QSContainerController {
- fun setCustomizerAnimating(animating: Boolean)
-
- fun setCustomizerShowing(showing: Boolean) = setCustomizerShowing(showing, 0L)
-
- fun setCustomizerShowing(showing: Boolean, animationDuration: Long)
-
- fun setDetailShowing(showing: Boolean)
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSFactory.java b/systemUIPlugin/src/com/android/systemui/plugins/qs/QSFactory.java
deleted file mode 100644
index cfe3be0acc..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSFactory.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins.qs;
-
-import android.content.Context;
-
-import com.android.systemui.plugins.Plugin;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Plugin that has the ability to create or override any part of
- * QS tiles.
- */
-@ProvidesInterface(action = QSFactory.ACTION, version = QSFactory.VERSION)
-@DependsOn(target = QSTile.class)
-@DependsOn(target = QSTileView.class)
-public interface QSFactory extends Plugin {
-
- String ACTION = "com.android.systemui.action.PLUGIN_QS_FACTORY";
- int VERSION = 2;
-
- QSTile createTile(String tileSpec);
-
- /**
- * Create a view for a tile.
- *
- * @param context a themed context for inflating the view
- * @param tile the tile for which the view is created
- * @param collapsedView {@code true} if the view will live in QQS and {@code false} otherwise.
- * @return a view for the tile
- */
- QSTileView createTileView(Context context, QSTile tile, boolean collapsedView);
-
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSIconView.java b/systemUIPlugin/src/com/android/systemui/plugins/qs/QSIconView.java
deleted file mode 100644
index 0cdb509a52..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSIconView.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins.qs;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.qs.QSTile.State;
-
-@ProvidesInterface(version = QSIconView.VERSION)
-public abstract class QSIconView extends ViewGroup {
- public static final int VERSION = 1;
-
- public QSIconView(Context context) {
- super(context);
- }
-
- public abstract void setIcon(State state, boolean allowAnimations);
- public abstract void disableAnimation();
- public abstract View getIconView();
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSTile.java b/systemUIPlugin/src/com/android/systemui/plugins/qs/QSTile.java
deleted file mode 100644
index 25f77ea4e6..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins.qs;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.metrics.LogMaker;
-import android.service.quicksettings.Tile;
-import android.text.TextUtils;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.InstanceId;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.qs.QSTile.Callback;
-import com.android.systemui.plugins.qs.QSTile.Icon;
-import com.android.systemui.plugins.qs.QSTile.State;
-
-import java.util.Objects;
-import java.util.function.Supplier;
-
-@ProvidesInterface(version = QSTile.VERSION)
-@DependsOn(target = QSIconView.class)
-@DependsOn(target = Callback.class)
-@DependsOn(target = Icon.class)
-@DependsOn(target = State.class)
-public interface QSTile {
- int VERSION = 4;
-
- String getTileSpec();
-
- boolean isAvailable();
- void setTileSpec(String tileSpec);
-
- @Deprecated default void clearState() {}
- void refreshState();
-
- void addCallback(Callback callback);
- void removeCallback(Callback callback);
- void removeCallbacks();
-
- QSIconView createTileView(Context context);
-
- /**
- * The tile was clicked.
- *
- * @param view The view that was clicked.
- */
- void click(@Nullable View view);
-
- /**
- * The tile secondary click was triggered.
- *
- * @param view The view that was clicked.
- */
- void secondaryClick(@Nullable View view);
-
- /**
- * The tile was long clicked.
- *
- * @param view The view that was clicked.
- */
- void longClick(@Nullable View view);
-
- void userSwitch(int currentUser);
-
- /**
- * @deprecated not needed as {@link com.android.internal.logging.UiEvent} will use
- * {@link #getMetricsSpec}
- */
- @Deprecated
- int getMetricsCategory();
-
- void setListening(Object client, boolean listening);
- void setDetailListening(boolean show);
-
- void destroy();
-
- CharSequence getTileLabel();
-
- State getState();
-
- default LogMaker populate(LogMaker logMaker) {
- return logMaker;
- }
-
- /**
- * Return a string to be used to identify the tile in UiEvents.
- */
- default String getMetricsSpec() {
- return getClass().getSimpleName();
- }
-
- /**
- * Return an {@link InstanceId} to be used to identify the tile in UiEvents.
- */
- InstanceId getInstanceId();
-
- default boolean isTileReady() {
- return false;
- }
-
- /**
- * Return whether the tile is set to its listening state and therefore receiving updates and
- * refreshes from controllers
- */
- boolean isListening();
-
- @ProvidesInterface(version = Callback.VERSION)
- interface Callback {
- static final int VERSION = 2;
- void onStateChanged(State state);
- }
-
- @ProvidesInterface(version = Icon.VERSION)
- public static abstract class Icon {
- public static final int VERSION = 1;
- abstract public Drawable getDrawable(Context context);
-
- public Drawable getInvisibleDrawable(Context context) {
- return getDrawable(context);
- }
-
- @Override
- public int hashCode() {
- return Icon.class.hashCode();
- }
-
- public int getPadding() {
- return 0;
- }
-
- @Override
- @NonNull
- public String toString() {
- return "Icon";
- }
- }
-
- @ProvidesInterface(version = State.VERSION)
- public static class State {
- public static final int VERSION = 1;
- public static final int DEFAULT_STATE = Tile.STATE_ACTIVE;
-
- public Icon icon;
- public Supplier iconSupplier;
- public int state = DEFAULT_STATE;
- public CharSequence label;
- @Nullable public CharSequence secondaryLabel;
- public CharSequence contentDescription;
- @Nullable public CharSequence stateDescription;
- public CharSequence dualLabelContentDescription;
- public boolean disabledByPolicy;
- public boolean dualTarget = false;
- public boolean isTransient = false;
- public String expandedAccessibilityClassName;
- public SlashState slash;
- public boolean handlesLongClick = true;
- @Nullable
- public Drawable sideViewCustomDrawable;
- public String spec;
-
- /** Get the state text. */
- public String getStateText(int arrayResId, Resources resources) {
- if (state == Tile.STATE_UNAVAILABLE || this instanceof QSTile.BooleanState) {
- String[] array = resources.getStringArray(arrayResId);
- return array[state];
- } else {
- return "";
- }
- }
-
- /** Get the text for secondaryLabel. */
- public String getSecondaryLabel(String stateText) {
- // Use a local reference as the value might change from other threads
- CharSequence localSecondaryLabel = secondaryLabel;
- if (TextUtils.isEmpty(localSecondaryLabel)) {
- return stateText;
- }
- return localSecondaryLabel.toString();
- }
-
- public boolean copyTo(State other) {
- if (other == null) throw new IllegalArgumentException();
- if (!other.getClass().equals(getClass())) throw new IllegalArgumentException();
- final boolean changed = !Objects.equals(other.spec, spec)
- || !Objects.equals(other.icon, icon)
- || !Objects.equals(other.iconSupplier, iconSupplier)
- || !Objects.equals(other.label, label)
- || !Objects.equals(other.secondaryLabel, secondaryLabel)
- || !Objects.equals(other.contentDescription, contentDescription)
- || !Objects.equals(other.stateDescription, stateDescription)
- || !Objects.equals(other.dualLabelContentDescription,
- dualLabelContentDescription)
- || !Objects.equals(other.expandedAccessibilityClassName,
- expandedAccessibilityClassName)
- || !Objects.equals(other.disabledByPolicy, disabledByPolicy)
- || !Objects.equals(other.state, state)
- || !Objects.equals(other.isTransient, isTransient)
- || !Objects.equals(other.dualTarget, dualTarget)
- || !Objects.equals(other.slash, slash)
- || !Objects.equals(other.handlesLongClick, handlesLongClick)
- || !Objects.equals(other.sideViewCustomDrawable, sideViewCustomDrawable);
- other.spec = spec;
- other.icon = icon;
- other.iconSupplier = iconSupplier;
- other.label = label;
- other.secondaryLabel = secondaryLabel;
- other.contentDescription = contentDescription;
- other.stateDescription = stateDescription;
- other.dualLabelContentDescription = dualLabelContentDescription;
- other.expandedAccessibilityClassName = expandedAccessibilityClassName;
- other.disabledByPolicy = disabledByPolicy;
- other.state = state;
- other.dualTarget = dualTarget;
- other.isTransient = isTransient;
- other.slash = slash != null ? slash.copy() : null;
- other.handlesLongClick = handlesLongClick;
- other.sideViewCustomDrawable = sideViewCustomDrawable;
- return changed;
- }
-
- @Override
- public String toString() {
- return toStringBuilder().toString();
- }
-
- // Used in dumps to determine current state of a tile.
- // This string may be used for CTS testing of tiles, so removing elements is discouraged.
- protected StringBuilder toStringBuilder() {
- final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
- sb.append("spec=").append(spec);
- sb.append(",icon=").append(icon);
- sb.append(",iconSupplier=").append(iconSupplier);
- sb.append(",label=").append(label);
- sb.append(",secondaryLabel=").append(secondaryLabel);
- sb.append(",contentDescription=").append(contentDescription);
- sb.append(",stateDescription=").append(stateDescription);
- sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
- sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName);
- sb.append(",disabledByPolicy=").append(disabledByPolicy);
- sb.append(",dualTarget=").append(dualTarget);
- sb.append(",isTransient=").append(isTransient);
- sb.append(",state=").append(state);
- sb.append(",slash=\"").append(slash).append("\"");
- sb.append(",sideViewCustomDrawable=").append(sideViewCustomDrawable);
- return sb.append(']');
- }
-
- public State copy() {
- State state = new State();
- copyTo(state);
- return state;
- }
- }
-
- @ProvidesInterface(version = BooleanState.VERSION)
- public static class BooleanState extends State {
- public static final int VERSION = 1;
- public boolean value;
- public boolean forceExpandIcon;
-
- @Override
- public boolean copyTo(State other) {
- final BooleanState o = (BooleanState) other;
- final boolean changed = super.copyTo(other)
- || o.value != value
- || o.forceExpandIcon != forceExpandIcon;
- o.value = value;
- o.forceExpandIcon = forceExpandIcon;
- return changed;
- }
-
- @Override
- protected StringBuilder toStringBuilder() {
- final StringBuilder rt = super.toStringBuilder();
- rt.insert(rt.length() - 1, ",value=" + value);
- rt.insert(rt.length() - 1, ",forceExpandIcon=" + forceExpandIcon);
- return rt;
- }
-
- @Override
- public State copy() {
- BooleanState state = new BooleanState();
- copyTo(state);
- return state;
- }
- }
-
- @ProvidesInterface(version = SignalState.VERSION)
- public static final class SignalState extends BooleanState {
- public static final int VERSION = 1;
- public boolean activityIn;
- public boolean activityOut;
- public boolean isOverlayIconWide;
- public int overlayIconId;
-
- @Override
- public boolean copyTo(State other) {
- final SignalState o = (SignalState) other;
- final boolean changed = o.activityIn != activityIn
- || o.activityOut != activityOut
- || o.isOverlayIconWide != isOverlayIconWide
- || o.overlayIconId != overlayIconId;
- o.activityIn = activityIn;
- o.activityOut = activityOut;
- o.isOverlayIconWide = isOverlayIconWide;
- o.overlayIconId = overlayIconId;
- return super.copyTo(other) || changed;
- }
-
- @Override
- protected StringBuilder toStringBuilder() {
- final StringBuilder rt = super.toStringBuilder();
- rt.insert(rt.length() - 1, ",activityIn=" + activityIn);
- rt.insert(rt.length() - 1, ",activityOut=" + activityOut);
- return rt;
- }
-
- @Override
- public State copy() {
- SignalState state = new SignalState();
- copyTo(state);
- return state;
- }
- }
-
- @ProvidesInterface(version = SlashState.VERSION)
- public static class SlashState {
- public static final int VERSION = 2;
-
- public boolean isSlashed;
- public float rotation;
-
- @Override
- public String toString() {
- return "isSlashed=" + isSlashed + ",rotation=" + rotation;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == null) return false;
- try {
- return (((SlashState) o).rotation == rotation)
- && (((SlashState) o).isSlashed == isSlashed);
- } catch (ClassCastException e) {
- return false;
- }
- }
-
- public SlashState copy() {
- SlashState state = new SlashState();
- state.rotation = rotation;
- state.isSlashed = isSlashed;
- return state;
- }
- }
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSTileView.java b/systemUIPlugin/src/com/android/systemui/plugins/qs/QSTileView.java
deleted file mode 100644
index a8999ff31f..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/qs/QSTileView.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins.qs;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.qs.QSTile.State;
-
-@ProvidesInterface(version = QSTileView.VERSION)
-@DependsOn(target = QSIconView.class)
-@DependsOn(target = QSTile.class)
-public abstract class QSTileView extends LinearLayout {
- public static final int VERSION = 3;
-
- public QSTileView(Context context) {
- super(context);
- }
-
- public abstract View updateAccessibilityOrder(View previousView);
-
- /**
- * Returns a {@link QSIconView} containing only the icon for this tile. Use
- * {@link #getIconWithBackground()} to retrieve the entire tile (background & peripherals
- * included).
- */
- public abstract QSIconView getIcon();
-
- /**
- * Returns a {@link View} containing the icon for this tile along with the accompanying
- * background circle/peripherals. To retrieve only the inner icon, use {@link #getIcon()}.
- */
- public abstract View getIconWithBackground();
-
- /**
- * Returns the {@link View} containing the icon on the right
- *
- * @see com.android.systemui.qs.tileimpl.QSTileViewHorizontal#sideView
- */
- public View getSecondaryIcon() {
- return null;
- }
- public abstract void init(QSTile tile);
- public abstract void onStateChanged(State state);
-
- public abstract int getDetailY();
-
- public View getLabel() {
- return null;
- }
-
- public View getLabelContainer() {
- return null;
- }
-
- public View getSecondaryLabel() {
- return null;
- }
-
- /** Sets the index of this tile in its layout */
- public abstract void setPosition(int position);
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java b/systemUIPlugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java
deleted file mode 100644
index 678eb31304..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins.statusbar;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Retrieve doze information
- */
-@ProvidesInterface(version = DozeParameters.VERSION)
-public interface DozeParameters {
- int VERSION = 1;
-
- /**
- * Whether to doze when the screen turns off
- */
- boolean shouldControlScreenOff();
-}
diff --git a/systemUIPlugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java b/systemUIPlugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
deleted file mode 100644
index 94fdbae832..0000000000
--- a/systemUIPlugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.plugins.statusbar;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.Point;
-import android.service.notification.StatusBarNotification;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.systemui.plugins.Plugin;
-import com.android.systemui.plugins.annotations.DependsOn;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
-import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
-
-import java.util.ArrayList;
-
-@ProvidesInterface(action = NotificationMenuRowPlugin.ACTION,
- version = NotificationMenuRowPlugin.VERSION)
-@DependsOn(target = OnMenuEventListener.class)
-@DependsOn(target = MenuItem.class)
-@DependsOn(target = NotificationSwipeActionHelper.class)
-@DependsOn(target = SnoozeOption.class)
-public interface NotificationMenuRowPlugin extends Plugin {
-
- public static final String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_MENU_ROW";
- public static final int VERSION = 5;
-
- @ProvidesInterface(version = OnMenuEventListener.VERSION)
- public interface OnMenuEventListener {
- public static final int VERSION = 1;
-
- public void onMenuClicked(View row, int x, int y, MenuItem menu);
-
- public void onMenuReset(View row);
-
- public void onMenuShown(View row);
- }
-
- @ProvidesInterface(version = MenuItem.VERSION)
- public interface MenuItem {
- public static final int VERSION = 1;
-
- public View getMenuView();
-
- public View getGutsView();
-
- public String getContentDescription();
- }
-
- /**
- * @return a list of items to populate the menu 'behind' a notification.
- */
- public ArrayList