1 /*
2  * Copyright 2024 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.photopicker.core.configuration
18 
19 import android.provider.DeviceConfig
20 import android.util.Log
21 import java.util.concurrent.Executor
22 
23 /**
24  * A thin wrapper around [DeviceConfig]. This allows for isolating the device state during tests by
25  * providing an alternate implementation, however this implementation is intended to be used as the
26  * default for runtime device config checks.
27  */
28 class DeviceConfigProxyImpl : DeviceConfigProxy {
29 
addOnPropertiesChangedListenernull30     override fun addOnPropertiesChangedListener(
31         namespace: String,
32         executor: Executor,
33         listener: DeviceConfig.OnPropertiesChangedListener,
34     ) {
35         DeviceConfig.addOnPropertiesChangedListener(namespace, executor, listener)
36     }
37 
getFlagnull38     override fun <T> getFlag(namespace: String, key: String, defaultValue: T): T {
39 
40         // The casts below are definitely safe casts, Use of the "as?" ensures the type
41         // and in the case it cannot be cast to the type, instead default back to the provided
42         // default value which is known to match the correct type.
43         // As a result, we silence the unchecked cast compiler warnings in the block below.
44         return when (defaultValue) {
45             is Boolean ->
46                 @Suppress("UNCHECKED_CAST")
47                 (DeviceConfig.getBoolean(namespace, key, defaultValue) as? T) ?: defaultValue
48             is String ->
49                 @Suppress("UNCHECKED_CAST")
50                 (DeviceConfig.getString(namespace, key, defaultValue as String) as? T)
51                     ?: defaultValue
52             // The expected type is not supported, so return the default.
53             else -> {
54                 Log.w(
55                     ConfigurationManager.TAG,
56                     "Unexpected flag type was requested for $namespace/$key, and lookup is not" +
57                         " supported. The default value of $defaultValue will be returned."
58                 )
59                 return defaultValue
60             }
61         }
62     }
63 
removeOnPropertiesChangedListenernull64     override fun removeOnPropertiesChangedListener(
65         listener: DeviceConfig.OnPropertiesChangedListener
66     ) {
67         DeviceConfig.removeOnPropertiesChangedListener(listener)
68     }
69 }
70