1 /*
2  * Copyright (C) 2023 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.systemui.retail.data.repository.impl
18 
19 import android.database.ContentObserver
20 import android.provider.Settings
21 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
22 import com.android.systemui.dagger.SysUISingleton
23 import com.android.systemui.dagger.qualifiers.Application
24 import com.android.systemui.dagger.qualifiers.Background
25 import com.android.systemui.retail.data.repository.RetailModeRepository
26 import com.android.systemui.util.settings.GlobalSettings
27 import javax.inject.Inject
28 import kotlinx.coroutines.CoroutineDispatcher
29 import kotlinx.coroutines.CoroutineScope
30 import kotlinx.coroutines.channels.awaitClose
31 import kotlinx.coroutines.flow.SharingStarted
32 import kotlinx.coroutines.flow.StateFlow
33 import kotlinx.coroutines.flow.flowOn
34 import kotlinx.coroutines.flow.map
35 import kotlinx.coroutines.flow.onStart
36 import kotlinx.coroutines.flow.stateIn
37 
38 /**
39  * Tracks [Settings.Global.DEVICE_DEMO_MODE].
40  *
41  * @see UserManager.isDeviceInDemoMode
42  */
43 @SysUISingleton
44 class RetailModeSettingsRepository
45 @Inject
46 constructor(
47     globalSettings: GlobalSettings,
48     @Background backgroundDispatcher: CoroutineDispatcher,
49     @Application scope: CoroutineScope,
50 ) : RetailModeRepository {
51     override val retailMode =
<lambda>null52         conflatedCallbackFlow {
53                 val observer =
54                     object : ContentObserver(null) {
55                         override fun onChange(selfChange: Boolean) {
56                             trySend(Unit)
57                         }
58                     }
59 
60                 globalSettings.registerContentObserverSync(RETAIL_MODE_SETTING, observer)
61 
62                 awaitClose { globalSettings.unregisterContentObserverSync(observer) }
63             }
<lambda>null64             .onStart { emit(Unit) }
<lambda>null65             .map { globalSettings.getInt(RETAIL_MODE_SETTING, 0) != 0 }
66             .flowOn(backgroundDispatcher)
67             .stateIn(scope, SharingStarted.Eagerly, false)
68 
69     companion object {
70         private const val RETAIL_MODE_SETTING = Settings.Global.DEVICE_DEMO_MODE
71     }
72 }
73