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.qs.pipeline.domain.autoaddable
18 
19 import com.android.systemui.dagger.qualifiers.Background
20 import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
21 import com.android.systemui.qs.pipeline.domain.model.AutoAddTracking
22 import com.android.systemui.qs.pipeline.domain.model.AutoAddable
23 import com.android.systemui.qs.pipeline.shared.TileSpec
24 import com.android.systemui.util.settings.SecureSettings
25 import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
26 import dagger.assisted.Assisted
27 import dagger.assisted.AssistedFactory
28 import dagger.assisted.AssistedInject
29 import java.util.Objects
30 import kotlinx.coroutines.CoroutineDispatcher
31 import kotlinx.coroutines.flow.Flow
32 import kotlinx.coroutines.flow.distinctUntilChanged
33 import kotlinx.coroutines.flow.filter
34 import kotlinx.coroutines.flow.flowOn
35 import kotlinx.coroutines.flow.map
36 import kotlinx.coroutines.flow.onStart
37 
38 /**
39  * It tracks a specific `Secure` int [setting] and when its value changes to non-zero, it will emit
40  * a [AutoAddSignal.Add] for [spec].
41  */
42 class AutoAddableSetting
43 @AssistedInject
44 constructor(
45     private val secureSettings: SecureSettings,
46     @Background private val bgDispatcher: CoroutineDispatcher,
47     @Assisted private val setting: String,
48     @Assisted private val spec: TileSpec,
49 ) : AutoAddable {
50 
autoAddSignalnull51     override fun autoAddSignal(userId: Int): Flow<AutoAddSignal> {
52         return secureSettings
53             .observerFlow(userId, setting)
54             .onStart { emit(Unit) }
55             .map { secureSettings.getIntForUser(setting, 0, userId) != 0 }
56             .distinctUntilChanged()
57             .filter { it }
58             .map { AutoAddSignal.Add(spec) }
59             .flowOn(bgDispatcher)
60     }
61 
62     override val autoAddTracking = AutoAddTracking.IfNotAdded(spec)
63 
64     override val description = "AutoAddableSetting: $setting:$spec ($autoAddTracking)"
65 
equalsnull66     override fun equals(other: Any?): Boolean {
67         return other is AutoAddableSetting && spec == other.spec && setting == other.setting
68     }
69 
hashCodenull70     override fun hashCode(): Int {
71         return Objects.hash(spec, setting)
72     }
73 
toStringnull74     override fun toString(): String {
75         return description
76     }
77 
78     @AssistedFactory
79     interface Factory {
createnull80         fun create(setting: String, spec: TileSpec): AutoAddableSetting
81     }
82 }
83