Skip to content

Commit 2c8b3c2

Browse files
neobuddy89joeyhuab
authored andcommitted
SystemUI: Add gradient for volume buttons along with slider
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
1 parent 681a9ec commit 2c8b3c2

2 files changed

Lines changed: 280 additions & 21 deletions

File tree

packages/SystemUI/src/com/android/systemui/volume/dialog/captions/ui/binder/VolumeDialogCaptionsButtonViewBinder.kt

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@
1616

1717
package com.android.systemui.volume.dialog.captions.ui.binder
1818

19+
import android.content.Context
20+
import android.database.ContentObserver
21+
import android.graphics.drawable.Drawable
22+
import android.graphics.drawable.GradientDrawable
23+
import android.graphics.drawable.InsetDrawable
1924
import android.graphics.drawable.TransitionDrawable
2025
import android.os.Handler
26+
import android.os.UserHandle
27+
import android.provider.Settings
2128
import android.view.View
2229
import com.android.app.tracing.coroutines.launchInTraced
2330
import com.android.app.tracing.coroutines.launchTraced
31+
import com.android.internal.R as internalR
2432
import com.android.systemui.Flags
2533
import com.android.systemui.dagger.qualifiers.Background
2634
import com.android.systemui.res.R
@@ -34,6 +42,7 @@ import javax.inject.Inject
3442
import kotlinx.coroutines.CoroutineScope
3543
import kotlinx.coroutines.flow.onEach
3644
import kotlinx.coroutines.flow.withIndex
45+
import kotlinx.coroutines.job
3746

3847
/** Binds the captions button view. */
3948
@VolumeDialogScope
@@ -55,6 +64,39 @@ constructor(
5564
dialogViewModel.addTouchableBounds(captionsButton)
5665
}
5766

67+
val contentResolver = captionsButton.context.contentResolver
68+
var gradientEnabled = isVolumeGradientEnabled(captionsButton.context)
69+
var gradientColorsForRinger = getGradientColorsForRinger(captionsButton.context)
70+
71+
val gradientObserver =
72+
object : ContentObserver(null) {
73+
override fun onChange(selfChange: Boolean) {
74+
gradientEnabled = isVolumeGradientEnabled(view.context)
75+
gradientColorsForRinger = getGradientColorsForRinger(view.context)
76+
}
77+
}
78+
79+
contentResolver.registerContentObserver(
80+
Settings.System.getUriFor(Settings.System.VOLUME_SLIDER_GRADIENT),
81+
false, gradientObserver, UserHandle.USER_ALL,
82+
)
83+
contentResolver.registerContentObserver(
84+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_COLOR_MODE),
85+
false, gradientObserver, UserHandle.USER_ALL,
86+
)
87+
contentResolver.registerContentObserver(
88+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_START_COLOR),
89+
false, gradientObserver, UserHandle.USER_ALL,
90+
)
91+
contentResolver.registerContentObserver(
92+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_END_COLOR),
93+
false, gradientObserver, UserHandle.USER_ALL,
94+
)
95+
96+
coroutineContext.job.invokeOnCompletion {
97+
contentResolver.unregisterContentObserver(gradientObserver)
98+
}
99+
58100
viewModel.isVisible
59101
.onEach { isVisible ->
60102
captionsButton.visibility =
@@ -88,6 +130,10 @@ constructor(
88130
)
89131
)
90132

133+
if (isEnabled && gradientEnabled) {
134+
applyGradientSelectionBackground(this, gradientColorsForRinger)
135+
}
136+
91137
val transition = background as TransitionDrawable
92138
transition.isCrossFadeEnabled = true
93139
if (index == 0) {
@@ -116,7 +162,70 @@ constructor(
116162
)
117163
}
118164

165+
private fun isVolumeGradientEnabled(context: Context): Boolean {
166+
return Settings.System.getIntForUser(
167+
context.contentResolver, Settings.System.VOLUME_SLIDER_GRADIENT, 0,
168+
UserHandle.USER_CURRENT) != 0
169+
}
170+
171+
private fun getGradientColorsForRinger(context: Context): Pair<Int, Int> {
172+
val resolver = context.contentResolver
173+
174+
val mode = Settings.System.getIntForUser(
175+
resolver, Settings.System.CUSTOM_GRADIENT_COLOR_MODE, 0,
176+
UserHandle.USER_CURRENT,
177+
)
178+
179+
val primary = context.getColor(internalR.color.materialColorPrimary)
180+
val secondary = context.getColor(internalR.color.materialColorSecondary)
181+
182+
if (mode == 1) {
183+
val start = Settings.System.getIntForUser(
184+
resolver, Settings.System.CUSTOM_GRADIENT_START_COLOR, 0,
185+
UserHandle.USER_CURRENT,
186+
)
187+
val end = Settings.System.getIntForUser(
188+
resolver, Settings.System.CUSTOM_GRADIENT_END_COLOR, 0,
189+
UserHandle.USER_CURRENT,
190+
)
191+
192+
val startColor = if (start != 0) start else primary
193+
val endColor = if (end != 0) end else secondary
194+
195+
return startColor to endColor
196+
}
197+
198+
return primary to secondary
199+
}
200+
201+
private fun applyGradientSelectionBackground(
202+
button: CaptionsToggleImageButton,
203+
gradientColorsForRinger: Pair<Int, Int>,
204+
) {
205+
val (startColor, endColor) = gradientColorsForRinger
206+
val shape = button.backgroundShape()
207+
shape.orientation = GradientDrawable.Orientation.TOP_BOTTOM
208+
shape.colors = intArrayOf(startColor, endColor)
209+
button.background.invalidateSelf()
210+
}
211+
119212
private companion object {
120213
const val DURATION_MILLIS = 500
121214
}
122215
}
216+
217+
private fun CaptionsToggleImageButton.backgroundShape(): GradientDrawable {
218+
val td = background as TransitionDrawable
219+
220+
fun unwrap(d: Drawable): GradientDrawable? {
221+
return when (d) {
222+
is GradientDrawable -> d
223+
is InsetDrawable -> d.drawable as? GradientDrawable
224+
else -> null
225+
}
226+
}
227+
228+
return unwrap(td.getDrawable(1))
229+
?: unwrap(td.getDrawable(0))
230+
?: throw IllegalStateException("Captions button background is not a GradientDrawable")
231+
}

0 commit comments

Comments
 (0)