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

Commit efcb4dfd authored by Jacky Wang's avatar Jacky Wang
Browse files

[Catalyst] Migrate AmbientDisplayAlwaysOnPreferenceController

As the preference is exported as external settings, for safety, do not
update the preference key with datastore key. As a workaround, manage a
mapping between preference hierarchy key and datastore key.

Bug: 372307567
Flag: com.android.settings.flags.catalyst_lockscreen_from_display_settings
Test: devtool
Change-Id: I56126485061859b41216cd23b8e1caf63823a1ec
parent b6132572
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -186,7 +186,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
    }

    /** Returns if catalyst is enabled on current screen. */
    protected final boolean isCatalystEnabled() {
    public final boolean isCatalystEnabled() {
        // TODO(b/379130874): make Catalyst compatible with desktop device, such as user restriction
        // check.
        Context context = getContext();
+116 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.settings.display

import android.content.Context
import android.hardware.display.AmbientDisplayConfiguration
import android.os.SystemProperties
import android.os.UserHandle
import android.os.UserManager
import android.provider.Settings.Secure.DOZE_ALWAYS_ON
import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R
import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime
import com.android.settingslib.datastore.HandlerExecutor
import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.KeyedObservableDelegate
import com.android.settingslib.datastore.KeyedObserver
import com.android.settingslib.datastore.SettingsSecureStore
import com.android.settingslib.datastore.SettingsStore
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceLifecycleContext
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.ReadWritePermit
import com.android.settingslib.metadata.SwitchPreference

// LINT.IfChange
class AmbientDisplayAlwaysOnPreference :
    SwitchPreference(KEY, R.string.doze_always_on_title, R.string.doze_always_on_summary),
    PreferenceAvailabilityProvider,
    PreferenceSummaryProvider,
    PreferenceLifecycleProvider,
    PreferenceRestrictionMixin {

    private var keyMappingObserver: KeyedObserver<String>? = null

    override val keywords: Int
        get() = R.string.keywords_always_show_time_info

    override val restrictionKeys: Array<String>
        get() = arrayOf(UserManager.DISALLOW_AMBIENT_DISPLAY)

    override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)

    override fun isAvailable(context: Context) =
        !SystemProperties.getBoolean(PROP_AWARE_AVAILABLE, false) &&
            AmbientDisplayConfiguration(context).alwaysOnAvailableForUser(UserHandle.myUserId())

    override fun getSummary(context: Context): CharSequence? =
        context.getText(
            when {
                isAodSuppressedByBedtime(context) -> R.string.aware_summary_when_bedtime_on
                else -> R.string.doze_always_on_summary
            }
        )

    override fun storage(context: Context): KeyValueStore = Storage(context)

    override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
        ReadWritePermit.ALLOW

    override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
        ReadWritePermit.ALLOW

    override fun onCreate(context: PreferenceLifecycleContext) {
        val storage = SettingsSecureStore.get(context)
        keyMappingObserver =
            KeyedObserver<String> { _, reason -> storage.notifyChange(KEY, reason) }
                .also { storage.addObserver(DOZE_ALWAYS_ON, it, HandlerExecutor.main) }
    }

    override fun onDestroy(context: PreferenceLifecycleContext) {
        keyMappingObserver?.let {
            SettingsSecureStore.get(context).removeObserver(DOZE_ALWAYS_ON, it)
        }
    }

    @Suppress("UNCHECKED_CAST")
    class Storage(
        private val context: Context,
        private val settingsStore: SettingsStore = SettingsSecureStore.get(context),
    ) : KeyedObservableDelegate<String>(settingsStore), KeyValueStore {

        override fun contains(key: String) = settingsStore.contains(DOZE_ALWAYS_ON)

        override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) =
            context.resources.getBoolean(com.android.internal.R.bool.config_dozeAlwaysOnEnabled)
                as T

        override fun <T : Any> getValue(key: String, valueType: Class<T>) =
            settingsStore.getValue(DOZE_ALWAYS_ON, valueType) ?: getDefaultValue(key, valueType)

        override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) =
            settingsStore.setValue(DOZE_ALWAYS_ON, valueType, value)
    }

    companion object {
        const val KEY = "ambient_display_always_on"
        private const val PROP_AWARE_AVAILABLE = "ro.vendor.aware_available"
    }
}
// LINT.ThenChange(AmbientDisplayAlwaysOnPreferenceController.java)
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;

// LINT.IfChange
public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreferenceController {

    private final int ON = 1;
@@ -130,3 +131,4 @@ public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreference
        return powerManager.isAmbientDisplaySuppressedForTokenByApp(AOD_SUPPRESSED_TOKEN, uid);
    }
}
// LINT.ThenChange(AmbientDisplayAlwaysOnPreference.kt)
+8 −1
Original line number Diff line number Diff line
@@ -17,8 +17,12 @@ package com.android.settings.security

import android.content.Context
import com.android.settings.R
import com.android.settings.Settings.LockScreenSettingsActivity
import com.android.settings.display.AmbientDisplayAlwaysOnPreference
import com.android.settings.flags.Flags
import com.android.settings.notification.LockScreenNotificationPreferenceController
import com.android.settings.utils.makeLaunchIntent
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.preferenceHierarchy
@@ -44,9 +48,12 @@ open class LockScreenPreferenceScreen : PreferenceScreenCreator, PreferenceSumma

    override fun fragmentClass() = LockscreenDashboardFragment::class.java

    override fun getLaunchIntent(context: Context, metadata: PreferenceMetadata?) =
        makeLaunchIntent(context, LockScreenSettingsActivity::class.java, metadata?.key)

    override fun getPreferenceHierarchy(context: Context) =
        preferenceHierarchy(this) {
            // add hierarchy here
            +AmbientDisplayAlwaysOnPreference()
        }

    companion object {
+3 −3
Original line number Diff line number Diff line
@@ -56,8 +56,6 @@ import java.util.List;
public class LockscreenDashboardFragment extends DashboardFragment
        implements OwnerInfoPreferenceController.OwnerInfoCallback {

    public static final String KEY_AMBIENT_DISPLAY_ALWAYS_ON = "ambient_display_always_on";

    private static final String TAG = "LockscreenDashboardFragment";

    @VisibleForTesting
@@ -111,7 +109,9 @@ public class LockscreenDashboardFragment extends DashboardFragment
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (!isCatalystEnabled()) {
            use(AmbientDisplayAlwaysOnPreferenceController.class).setConfig(getConfig(context));
        }
        use(AmbientDisplayNotificationsPreferenceController.class).setConfig(getConfig(context));
        use(DoubleTapScreenPreferenceController.class).setConfig(getConfig(context));
        use(PickupGesturePreferenceController.class).setConfig(getConfig(context));
Loading