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.internal.config.appcloning;
18 
19 import android.content.Context;
20 import android.provider.DeviceConfig;
21 
22 import com.android.internal.annotations.GuardedBy;
23 
24 /**
25  * Helper class that holds the flags related to the app_cloning namespace in {@link DeviceConfig}.
26  *
27  * @hide
28  */
29 public class AppCloningDeviceConfigHelper {
30 
31     @GuardedBy("sLock")
32     private static AppCloningDeviceConfigHelper sInstance;
33 
34     private static final Object sLock = new Object();
35 
36     private DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangeListener;
37 
38     /**
39      * This flag is defined inside {@link DeviceConfig#NAMESPACE_APP_CLONING}. Please check
40      * {@link #mEnableAppCloningBuildingBlocks} for details.
41      */
42     public static final String ENABLE_APP_CLONING_BUILDING_BLOCKS =
43             "enable_app_cloning_building_blocks";
44 
45     /**
46      * Checks whether the support for app-cloning building blocks (like contacts
47      * sharing/intent redirection), which are available starting from the U release, is turned on.
48      * The default value is true to ensure the features are always enabled going forward.
49      *
50      * TODO:(b/253449368) Add information about the app-cloning config and mention that the devices
51      * that do not support app-cloning should use the app-cloning config to disable all app-cloning
52      * features.
53      */
54     private volatile boolean mEnableAppCloningBuildingBlocks = true;
55 
AppCloningDeviceConfigHelper()56     private AppCloningDeviceConfigHelper() {}
57 
58     /**
59      * @hide
60      */
getInstance(Context context)61     public static AppCloningDeviceConfigHelper getInstance(Context context) {
62         synchronized (sLock) {
63             if (sInstance == null) {
64                 sInstance = new AppCloningDeviceConfigHelper();
65                 sInstance.init(context);
66             }
67             return sInstance;
68         }
69     }
70 
init(Context context)71     private void init(Context context) {
72         initializeDeviceConfigChangeListener();
73         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APP_CLONING,
74                 context.getMainExecutor(),
75                 mDeviceConfigChangeListener);
76     }
77 
initializeDeviceConfigChangeListener()78     private void initializeDeviceConfigChangeListener() {
79         mDeviceConfigChangeListener = properties -> {
80             if (!DeviceConfig.NAMESPACE_APP_CLONING.equals(properties.getNamespace())) {
81                 return;
82             }
83             for (String name : properties.getKeyset()) {
84                 if (name == null) {
85                     return;
86                 }
87                 if (ENABLE_APP_CLONING_BUILDING_BLOCKS.equals(name)) {
88                     updateEnableAppCloningBuildingBlocks();
89                 }
90             }
91         };
92     }
93 
updateEnableAppCloningBuildingBlocks()94     private void updateEnableAppCloningBuildingBlocks() {
95         mEnableAppCloningBuildingBlocks = DeviceConfig.getBoolean(
96                 DeviceConfig.NAMESPACE_APP_CLONING, ENABLE_APP_CLONING_BUILDING_BLOCKS, true);
97     }
98 
99     /**
100      * Fetch the feature flag to check whether the support for the app-cloning building blocks
101      * (like contacts sharing/intent redirection) is enabled on the device.
102      * @hide
103      */
getEnableAppCloningBuildingBlocks()104     public boolean getEnableAppCloningBuildingBlocks() {
105         return mEnableAppCloningBuildingBlocks;
106     }
107 }
108