1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settingslib.widget 18 19 import android.content.Context 20 import android.os.Build 21 import com.android.settingslib.widget.theme.flags.Flags 22 23 object SettingsThemeHelper { 24 private const val IS_EXPRESSIVE_DESIGN_ENABLED = "is_expressive_design_enabled" 25 private const val RO_BUILD_CHARACTERISTICS = "ro.build.characteristics" 26 private var expressiveThemeState: ExpressiveThemeState = ExpressiveThemeState.UNKNOWN 27 28 enum class ExpressiveThemeState { 29 UNKNOWN, 30 ENABLED, 31 DISABLED, 32 } 33 34 @JvmStatic isExpressiveThemenull35 fun isExpressiveTheme(context: Context): Boolean { 36 tryInit(context) 37 if (expressiveThemeState == ExpressiveThemeState.UNKNOWN) { 38 throw Exception( 39 "need to call com.android.settingslib.widget.SettingsThemeHelper.init(Context) first." 40 ) 41 } 42 43 return expressiveThemeState == ExpressiveThemeState.ENABLED 44 } 45 46 @JvmStatic isTabletnull47 fun isTablet(context: Context): Boolean { 48 val result = getPropString(context, RO_BUILD_CHARACTERISTICS, "").split(',') 49 return result.contains("tablet") 50 } 51 tryInitnull52 private fun tryInit(context: Context) { 53 expressiveThemeState = 54 if ( 55 (Build.VERSION.SDK_INT > Build.VERSION_CODES.VANILLA_ICE_CREAM) && 56 (getPropBoolean(context, IS_EXPRESSIVE_DESIGN_ENABLED, false) || 57 Flags.isExpressiveDesignEnabled()) 58 ) { 59 ExpressiveThemeState.ENABLED 60 } else { 61 ExpressiveThemeState.DISABLED 62 } 63 } 64 getPropBooleannull65 private fun getPropBoolean(context: Context, property: String, def: Boolean): Boolean { 66 return try { 67 val systemProperties = context.classLoader.loadClass("android.os.SystemProperties") 68 69 val paramTypes = 70 arrayOf<Class<*>?>(String::class.java, Boolean::class.javaPrimitiveType) 71 val getBoolean = systemProperties.getMethod("getBoolean", *paramTypes) 72 73 val params = arrayOf<Any>(property, def) 74 getBoolean.invoke(systemProperties, *params) as Boolean 75 } catch (iae: IllegalArgumentException) { 76 throw iae 77 } catch (exception: Exception) { 78 def 79 } 80 } 81 getPropStringnull82 private fun getPropString(context: Context, property: String, def: String): String { 83 return try { 84 val systemProperties = context.classLoader.loadClass("android.os.SystemProperties") 85 86 val paramTypes = 87 arrayOf<Class<*>?>(String::class.java, String::class.java) 88 val get = systemProperties.getMethod("get", *paramTypes) 89 get.invoke(systemProperties, property, def) as String 90 } catch (iae: IllegalArgumentException) { 91 throw iae 92 } catch (exception: Exception) { 93 def 94 } 95 } 96 } 97