Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3528988e authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add ExpressiveDesignEnabledProvider to allow activity control it" into main

parents 194216d5 74de87be
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
/*
* Copyright (C) 2025 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.settingslib.widget

/**
 * Optional interface that can be implemented by activities to provide whether expressive design
 * should be enabled if all other conditions are met.
 */
interface ExpressiveDesignEnabledProvider {
    fun isExpressiveDesignEnabled(): Boolean
}
+30 −28
Original line number Diff line number Diff line
@@ -16,49 +16,51 @@

package com.android.settingslib.widget

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.os.Build
import com.android.settingslib.widget.theme.flags.Flags

object SettingsThemeHelper {
    private const val IS_EXPRESSIVE_DESIGN_ENABLED = "is_expressive_design_enabled"
    private const val RO_BUILD_CHARACTERISTICS = "ro.build.characteristics"
    private var expressiveThemeState: ExpressiveThemeState = ExpressiveThemeState.UNKNOWN

    enum class ExpressiveThemeState {
        UNKNOWN,
        ENABLED,
        DISABLED,
    @JvmStatic
    fun isTablet(context: Context): Boolean {
        val result = getPropString(context, RO_BUILD_CHARACTERISTICS, "").split(',')
        return result.contains("tablet")
    }

    @JvmStatic
    fun isExpressiveTheme(context: Context): Boolean {
        tryInit(context)
        if (expressiveThemeState == ExpressiveThemeState.UNKNOWN) {
            throw Exception(
                "need to call com.android.settingslib.widget.SettingsThemeHelper.init(Context) first."
            )
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.BAKLAVA) {
            return false
        }

        return expressiveThemeState == ExpressiveThemeState.ENABLED
        // Enable if overridden by system property
        if (getPropBoolean(context, IS_EXPRESSIVE_DESIGN_ENABLED, false)) {
            return true;
        }

    @JvmStatic
    fun isTablet(context: Context): Boolean {
        val result = getPropString(context, RO_BUILD_CHARACTERISTICS, "").split(',')
        return result.contains("tablet")
        // Disable if feature flag is disabled.
        if (!Flags.isExpressiveDesignEnabled()) {
            return false;
        }
        // Allow the activity to override.
        val activity = getActivityFromContext(context)
        if (activity is ExpressiveDesignEnabledProvider) {
            return activity.isExpressiveDesignEnabled()
        }
        return true
    }

    private fun tryInit(context: Context) {
        expressiveThemeState =
            if (
                (Build.VERSION.SDK_INT > Build.VERSION_CODES.VANILLA_ICE_CREAM) &&
                        (getPropBoolean(context, IS_EXPRESSIVE_DESIGN_ENABLED, false) ||
                                Flags.isExpressiveDesignEnabled())
            ) {
                ExpressiveThemeState.ENABLED
            } else {
                ExpressiveThemeState.DISABLED
    private fun getActivityFromContext(context: Context): Activity? {
        var currentContext = context
        while (true) {
            when (currentContext) {
                is Activity -> return currentContext
                is ContextWrapper -> currentContext = currentContext.baseContext
                else -> return null
            }
        }
    }