/*
* 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 androidx.core.performance
import android.os.Build
/**
* Reports the media performance class of the device. Contains statically specified values
* and can be used as a fallback alternative to suppliers with dynamic values.
*/
class DefaultDevicePerformance() : DevicePerformance {
private val PERFCLASS_11: Int = Build.VERSION_CODES.R
private val PERFCLASS_12: Int = Build.VERSION_CODES.S
private val PERFCLASS_13: Int = Build.VERSION_CODES.TIRAMISU
private val PERFCLASS_NONE: Int = 0
private val fingerprints: HashMap<String, Int> = hashMapOf(
// for unit testing, no actual products with these
"robolectric-BrandX/ProductX/Device30:11" to PERFCLASS_11,
"robolectric-BrandX/ProductX/Device31:12" to PERFCLASS_12,
// actual devices in the field
"OPPO/CPH2025EEA/OP4BA2L1:12" to PERFCLASS_11,
"OPPO/CPH2207EEA/OP4F0BL1:12" to PERFCLASS_11,
"OPPO/PENM00/OP4EC1:11" to PERFCLASS_11,
"OnePlus/OnePlus7TTMO/OnePlus7TTMO:11" to PERFCLASS_11,
"OnePlus/OnePlus8_BETA/OnePlus8:11" to PERFCLASS_11,
"Xiaomi/umi_global/umi:11" to PERFCLASS_11,
"realme/RMX2085/RMX2085L1:11" to PERFCLASS_11,
"samsung/c1qsqw/c1q:12" to PERFCLASS_11,
"samsung/o1quew/o1q:12" to PERFCLASS_11,
"samsung/r0quew/r0q:12" to PERFCLASS_11,
"samsung/r0sxxx/r0s:12" to PERFCLASS_11,
)
override val mediaPerformanceClass = getCalculatedMediaPerformanceClass()
private fun getMediaPerformanceClassFromFingerprint(): Int {
val brand = Build.BRAND
val product = Build.PRODUCT
val device = Build.DEVICE
val release = Build.VERSION.RELEASE
val synthesized = "$brand/$product/$device:$release"
var pc = fingerprints[synthesized]
if (pc == null) {
pc = PERFCLASS_NONE
}
return pc
}
private fun getMediaPerformanceClassFromProperty(): Int {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
return Build.VERSION.MEDIA_PERFORMANCE_CLASS
}
return PERFCLASS_NONE
}
private fun isPerformanceClassValid(pc: Int): Boolean = pc >= PERFCLASS_11
private fun getCalculatedMediaPerformanceClass(): Int {
// device's declared property takes precedence over our in-library table.
val mpcViaProperty: Int =
getMediaPerformanceClassFromProperty()
if (isPerformanceClassValid(mpcViaProperty)) {
return mpcViaProperty
}
val mpcViaFingerprint: Int =
getMediaPerformanceClassFromFingerprint()
if (isPerformanceClassValid(mpcViaFingerprint)) {
return mpcViaFingerprint
}
return PERFCLASS_NONE
}
}