blob: ed175ef7a0957fc0e23482ce94f10251e01afa88 [file] [log] [blame]
/*
* 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.decor
import android.annotation.ArrayRes
import android.annotation.DrawableRes
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.util.DisplayUtils
import android.util.Size
import android.view.RoundedCorners
import com.android.systemui.Dumpable
import com.android.systemui.R
import java.io.PrintWriter
class RoundedCornerResDelegate(
private val res: Resources,
private var displayUniqueId: String?
) : Dumpable {
private val density: Float
get() = res.displayMetrics.density
var isMultipleRadius: Boolean = false
private set
private var roundedDrawable: Drawable? = null
var topRoundedDrawable: Drawable? = null
private set
var bottomRoundedDrawable: Drawable? = null
private set
private var roundedSize = Size(0, 0)
var topRoundedSize = Size(0, 0)
private set
var bottomRoundedSize = Size(0, 0)
private set
init {
reloadRes()
reloadMeasures()
}
fun reloadAll(newDisplayUniqueId: String?) {
displayUniqueId = newDisplayUniqueId
reloadRes()
reloadMeasures()
}
private fun reloadRes() {
val configIdx = DisplayUtils.getDisplayUniqueIdConfigIndex(res, displayUniqueId)
isMultipleRadius = getIsMultipleRadius(configIdx)
roundedDrawable = getDrawable(
displayConfigIndex = configIdx,
arrayResId = R.array.config_roundedCornerDrawableArray,
backupDrawableId = R.drawable.rounded
)
topRoundedDrawable = getDrawable(
displayConfigIndex = configIdx,
arrayResId = R.array.config_roundedCornerTopDrawableArray,
backupDrawableId = R.drawable.rounded_corner_top
) ?: roundedDrawable
bottomRoundedDrawable = getDrawable(
displayConfigIndex = configIdx,
arrayResId = R.array.config_roundedCornerBottomDrawableArray,
backupDrawableId = R.drawable.rounded_corner_bottom
) ?: roundedDrawable
}
private fun reloadMeasures(roundedSizeFactor: Int? = null) {
// If config_roundedCornerMultipleRadius set as true, ScreenDecorations respect the
// (width, height) size of drawable/rounded.xml instead of rounded_corner_radius
if (isMultipleRadius) {
roundedSize = Size(
roundedDrawable?.intrinsicWidth ?: 0,
roundedDrawable?.intrinsicHeight ?: 0)
topRoundedDrawable?.let {
topRoundedSize = Size(it.intrinsicWidth, it.intrinsicHeight)
}
bottomRoundedDrawable?.let {
bottomRoundedSize = Size(it.intrinsicWidth, it.intrinsicHeight)
}
} else {
val defaultRadius = RoundedCorners.getRoundedCornerRadius(res, displayUniqueId)
val topRadius = RoundedCorners.getRoundedCornerTopRadius(res, displayUniqueId)
val bottomRadius = RoundedCorners.getRoundedCornerBottomRadius(res, displayUniqueId)
roundedSize = Size(defaultRadius, defaultRadius)
topRoundedSize = Size(topRadius, topRadius)
bottomRoundedSize = Size(bottomRadius, bottomRadius)
}
if (topRoundedSize.width == 0) {
topRoundedSize = roundedSize
}
if (bottomRoundedSize.width == 0) {
bottomRoundedSize = roundedSize
}
if (roundedSizeFactor != null && roundedSizeFactor > 0) {
val length: Int = (roundedSizeFactor * density).toInt()
topRoundedSize = Size(length, length)
bottomRoundedSize = Size(length, length)
}
}
fun updateTuningSizeFactor(factor: Int) {
reloadMeasures(factor)
}
/**
* Gets whether the rounded corners are multiple radii for current display.
*
* Loads the default config {@link R.bool#config_roundedCornerMultipleRadius} if
* {@link com.android.internal.R.array#config_displayUniqueIdArray} is not set.
*/
private fun getIsMultipleRadius(displayConfigIndex: Int): Boolean {
val isMultipleRadius: Boolean
res.obtainTypedArray(R.array.config_roundedCornerMultipleRadiusArray).let { array ->
isMultipleRadius = if (displayConfigIndex >= 0 && displayConfigIndex < array.length()) {
array.getBoolean(displayConfigIndex, false)
} else {
res.getBoolean(R.bool.config_roundedCornerMultipleRadius)
}
array.recycle()
}
return isMultipleRadius
}
private fun getDrawable(
displayConfigIndex: Int,
@ArrayRes arrayResId: Int,
@DrawableRes backupDrawableId: Int
): Drawable? {
val drawable: Drawable?
res.obtainTypedArray(arrayResId).let { array ->
drawable = if (displayConfigIndex >= 0 && displayConfigIndex < array.length()) {
array.getDrawable(displayConfigIndex)
} else {
res.getDrawable(backupDrawableId, null)
}
array.recycle()
}
return drawable
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println("RoundedCornerResDelegate state:")
pw.println(" isMultipleRadius:$isMultipleRadius")
pw.println(" roundedSize(w,h)=(${roundedSize.width},${roundedSize.height})")
pw.println(" topRoundedSize(w,h)=(${topRoundedSize.width},${topRoundedSize.height})")
pw.println(" bottomRoundedSize(w,h)=(${bottomRoundedSize.width}," +
"${bottomRoundedSize.height})")
}
}