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

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

Merge "Inline user_aware_settings_repositories" into main

parents ed67219f 8ee111fa
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -1348,16 +1348,6 @@ flag {
  }
}

flag {
  namespace: "systemui"
  name: "user_aware_settings_repositories"
  description: "Provide user-aware versions of SecureSettingsRepository and SystemSettingsRepository in SystemUI modules (see doc linked from b/356099784)."
  bug: "356099784"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
    name: "notify_password_text_view_user_activity_in_background"
    namespace: "systemui"
+2 −0
Original line number Diff line number Diff line
@@ -33,5 +33,7 @@ interface SecureSettingsRepository {

    suspend fun getInt(name: String, defaultValue: Int = 0): Int

    suspend fun setBoolean(name: String, value: Boolean)

    suspend fun getString(name: String): String?
}
+0 −85
Original line number Diff line number Diff line
/*
 * 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 com.android.systemui.shared.settings.data.repository

import android.content.ContentResolver
import android.database.ContentObserver
import android.provider.Settings
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext

/**
 * Simple implementation of [SecureSettingsRepository].
 *
 * This repository doesn't guarantee to provide value across different users, and therefore
 * shouldn't be used in SystemUI. For that see: [UserAwareSecureSettingsRepository]
 */
// TODO: b/377244768 - Move to Theme/WallpaperPicker, away from SystemUI.
class SecureSettingsRepositoryImpl(
    private val contentResolver: ContentResolver,
    private val backgroundDispatcher: CoroutineDispatcher,
) : SecureSettingsRepository {

    override fun intSetting(name: String, defaultValue: Int): Flow<Int> {
        return callbackFlow {
                val observer =
                    object : ContentObserver(null) {
                        override fun onChange(selfChange: Boolean) {
                            trySend(Unit)
                        }
                    }

                contentResolver.registerContentObserver(
                    Settings.Secure.getUriFor(name),
                    /* notifyForDescendants= */ false,
                    observer,
                )
                send(Unit)

                awaitClose { contentResolver.unregisterContentObserver(observer) }
            }
            .map { Settings.Secure.getInt(contentResolver, name, defaultValue) }
            // The above work is done on the background thread (which is important for accessing
            // settings through the content resolver).
            .flowOn(backgroundDispatcher)
    }

    override fun boolSetting(name: String, defaultValue: Boolean): Flow<Boolean> {
        return intSetting(name, if (defaultValue) 1 else 0).map { it != 0 }
    }

    override suspend fun setInt(name: String, value: Int) {
        withContext(backgroundDispatcher) { Settings.Secure.putInt(contentResolver, name, value) }
    }

    override suspend fun getInt(name: String, defaultValue: Int): Int {
        return withContext(backgroundDispatcher) {
            Settings.Secure.getInt(contentResolver, name, defaultValue)
        }
    }

    override suspend fun getString(name: String): String? {
        return withContext(backgroundDispatcher) {
            Settings.Secure.getString(contentResolver, name)
        }
    }
}
+0 −85
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.systemui.shared.settings.data.repository

import android.content.ContentResolver
import android.database.ContentObserver
import android.provider.Settings
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext

/**
 * Defines interface for classes that can provide access to data from [Settings.System].
 *
 * This repository doesn't guarantee to provide value across different users. For that see:
 * [UserAwareSystemSettingsRepository].
 */
// TODO: b/377244768 - Move to Theme/WallpaperPicker, away from SystemUI.
class SystemSettingsRepositoryImpl(
    private val contentResolver: ContentResolver,
    private val backgroundDispatcher: CoroutineDispatcher,
) : SystemSettingsRepository {

    override fun intSetting(name: String, defaultValue: Int): Flow<Int> {
        return callbackFlow {
                val observer =
                    object : ContentObserver(null) {
                        override fun onChange(selfChange: Boolean) {
                            trySend(Unit)
                        }
                    }

                contentResolver.registerContentObserver(
                    Settings.System.getUriFor(name),
                    /* notifyForDescendants= */ false,
                    observer,
                )
                send(Unit)

                awaitClose { contentResolver.unregisterContentObserver(observer) }
            }
            .map { Settings.System.getInt(contentResolver, name, defaultValue) }
            // The above work is done on the background thread (which is important for accessing
            // settings through the content resolver).
            .flowOn(backgroundDispatcher)
    }

    override fun boolSetting(name: String, defaultValue: Boolean): Flow<Boolean> {
        return intSetting(name, if (defaultValue) 1 else 0).map { it != 0 }
    }

    override suspend fun setInt(name: String, value: Int) {
        withContext(backgroundDispatcher) { Settings.System.putInt(contentResolver, name, value) }
    }

    override suspend fun getInt(name: String, defaultValue: Int): Int {
        return withContext(backgroundDispatcher) {
            Settings.System.getInt(contentResolver, name, defaultValue)
        }
    }

    override suspend fun getString(name: String): String? {
        return withContext(backgroundDispatcher) {
            Settings.System.getString(contentResolver, name)
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ class FakeSecureSettingsRepository : SecureSettingsRepository {
        return intSetting(name, if (defaultValue) 1 else 0).map { it != 0 }
    }

    fun setBool(name: String, value: Boolean) {
    override suspend fun setBoolean(name: String, value: Boolean) {
        settings.value =
            settings.value.toMutableMap().apply { this[name] = (if (value) 1 else 0).toString() }
    }
Loading