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

Commit aebefab4 authored by Lyn Han's avatar Lyn Han Committed by Android (Google) Code Review
Browse files

Merge "StateFlow to check isCooldownEnabled in background" into main

parents 346eb81b 4d1174c7
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -18,9 +18,11 @@ package com.android.systemui.shared.notifications.data.repository

import android.provider.Settings
import com.android.systemui.shared.settings.data.repository.SecureSettingsRepository
import com.android.systemui.shared.settings.data.repository.SystemSettingsRepository
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
@@ -33,6 +35,7 @@ class NotificationSettingsRepository(
    private val scope: CoroutineScope,
    private val backgroundDispatcher: CoroutineDispatcher,
    private val secureSettingsRepository: SecureSettingsRepository,
    private val systemSettingsRepository: SystemSettingsRepository,
) {
    val isNotificationHistoryEnabled: Flow<Boolean> =
        secureSettingsRepository
@@ -60,4 +63,15 @@ class NotificationSettingsRepository(
            )
        }
    }

    val isCooldownEnabled: StateFlow<Boolean> =
        systemSettingsRepository
            .intSetting(name = Settings.System.NOTIFICATION_COOLDOWN_ENABLED)
            .map { it == 1 }
            .flowOn(backgroundDispatcher)
            .stateIn(
                scope = scope,
                started = SharingStarted.Eagerly,
                initialValue = false,
            )
}
+2 −1
Original line number Diff line number Diff line
@@ -38,4 +38,5 @@ class NotificationSettingsInteractor(
        val current = repository.isShowNotificationsOnLockScreenEnabled().value
        repository.setShowNotificationsOnLockscreenEnabled(!current)
    }
}

    val isCooldownEnabled = repository.isCooldownEnabled}
+117 −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.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:
 * [UserAwareSecureSettingsRepository] which does that for secure settings.
 */
interface SystemSettingsRepository {

    /** Returns a [Flow] tracking the value of a setting as an [Int]. */
    fun intSetting(
        name: String,
        defaultValue: Int = 0,
    ): Flow<Int>

    /** Updates the value of the setting with the given name. */
    suspend fun setInt(
        name: String,
        value: Int,
    )

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

    suspend fun getString(name: String): String?
}

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 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,
            )
        }
    }
}
+42 −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.systemui.shared.settings.data.repository

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map

class FakeSystemSettingsRepository : SystemSettingsRepository {

    private val settings = MutableStateFlow<Map<String, String>>(mutableMapOf())

    override fun intSetting(name: String, defaultValue: Int): Flow<Int> {
        return settings.map { it.getOrDefault(name, defaultValue.toString()) }.map { it.toInt() }
    }

    override suspend fun setInt(name: String, value: Int) {
        settings.value = settings.value.toMutableMap().apply { this[name] = value.toString() }
    }

    override suspend fun getInt(name: String, defaultValue: Int): Int {
        return settings.value[name]?.toInt() ?: defaultValue
    }

    override suspend fun getString(name: String): String? {
        return settings.value[name]
    }
}
+38 −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.systemui.settings

import android.content.ContentResolver
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.shared.settings.data.repository.SystemSettingsRepository
import com.android.systemui.shared.settings.data.repository.SystemSettingsRepositoryImpl
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.CoroutineDispatcher

@Module
object SystemSettingsRepositoryModule {
    @JvmStatic
    @Provides
    @SysUISingleton
    fun provideSystemSettingsRepository(
        contentResolver: ContentResolver,
        @Background backgroundDispatcher: CoroutineDispatcher,
    ): SystemSettingsRepository =
        SystemSettingsRepositoryImpl(contentResolver, backgroundDispatcher)
}
Loading