1 /* 2 * Copyright (C) 2022 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.server.nearby; 18 19 import android.os.Build; 20 import android.provider.DeviceConfig; 21 22 import androidx.annotation.NonNull; 23 24 import com.android.internal.annotations.GuardedBy; 25 import com.android.modules.utils.build.SdkLevel; 26 import com.android.server.nearby.managers.DiscoveryProviderManager; 27 28 import java.util.concurrent.Executors; 29 30 /** 31 * A utility class for encapsulating Nearby feature flag configurations. 32 */ 33 public class NearbyConfiguration { 34 35 /** 36 * Flag used to enable presence legacy broadcast. 37 */ 38 public static final String NEARBY_ENABLE_PRESENCE_BROADCAST_LEGACY = 39 "nearby_enable_presence_broadcast_legacy"; 40 /** 41 * Flag used to for minimum nano app version to make Nearby CHRE scan work. 42 */ 43 public static final String NEARBY_MAINLINE_NANO_APP_MIN_VERSION = 44 "nearby_mainline_nano_app_min_version"; 45 46 /** 47 * Flag used to allow test mode and customization. 48 */ 49 public static final String NEARBY_SUPPORT_TEST_APP = "nearby_support_test_app"; 50 51 /** 52 * Flag to control which version of DiscoveryProviderManager should be used. 53 */ 54 public static final String NEARBY_REFACTOR_DISCOVERY_MANAGER = 55 "nearby_refactor_discovery_manager"; 56 57 /** 58 * Flag to guard enable BLE during Nearby Service init time. 59 */ 60 public static final String NEARBY_ENABLE_BLE_IN_INIT = "nearby_enable_ble_in_init"; 61 62 private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 63 64 private final DeviceConfigListener mDeviceConfigListener = new DeviceConfigListener(); 65 private final Object mDeviceConfigLock = new Object(); 66 67 @GuardedBy("mDeviceConfigLock") 68 private boolean mEnablePresenceBroadcastLegacy; 69 @GuardedBy("mDeviceConfigLock") 70 private int mNanoAppMinVersion; 71 @GuardedBy("mDeviceConfigLock") 72 private boolean mSupportTestApp; 73 @GuardedBy("mDeviceConfigLock") 74 private boolean mRefactorDiscoveryManager; 75 @GuardedBy("mDeviceConfigLock") 76 private boolean mEnableBleInInit; 77 NearbyConfiguration()78 public NearbyConfiguration() { 79 mDeviceConfigListener.start(); 80 } 81 82 /** 83 * Returns the DeviceConfig namespace for Nearby. The {@link DeviceConfig#NAMESPACE_NEARBY} was 84 * added in UpsideDownCake, in Tiramisu, we use {@link DeviceConfig#NAMESPACE_TETHERING}. 85 */ getNamespace()86 public static String getNamespace() { 87 if (SdkLevel.isAtLeastU()) { 88 return DeviceConfig.NAMESPACE_NEARBY; 89 } 90 return DeviceConfig.NAMESPACE_TETHERING; 91 } 92 getDeviceConfigBoolean(final String name, final boolean defaultValue)93 private static boolean getDeviceConfigBoolean(final String name, final boolean defaultValue) { 94 final String value = getDeviceConfigProperty(name); 95 return value != null ? Boolean.parseBoolean(value) : defaultValue; 96 } 97 getDeviceConfigInt(final String name, final int defaultValue)98 private static int getDeviceConfigInt(final String name, final int defaultValue) { 99 final String value = getDeviceConfigProperty(name); 100 return value != null ? Integer.parseInt(value) : defaultValue; 101 } 102 getDeviceConfigProperty(String name)103 private static String getDeviceConfigProperty(String name) { 104 return DeviceConfig.getProperty(getNamespace(), name); 105 } 106 107 /** 108 * Returns whether broadcasting legacy presence spec is enabled. 109 */ isPresenceBroadcastLegacyEnabled()110 public boolean isPresenceBroadcastLegacyEnabled() { 111 synchronized (mDeviceConfigLock) { 112 return mEnablePresenceBroadcastLegacy; 113 } 114 } 115 getNanoAppMinVersion()116 public int getNanoAppMinVersion() { 117 synchronized (mDeviceConfigLock) { 118 return mNanoAppMinVersion; 119 } 120 } 121 122 /** 123 * @return {@code true} when in test mode and allows customization. 124 */ isTestAppSupported()125 public boolean isTestAppSupported() { 126 synchronized (mDeviceConfigLock) { 127 return mSupportTestApp; 128 } 129 } 130 131 /** 132 * @return {@code true} if use {@link DiscoveryProviderManager} or use 133 * DiscoveryProviderManagerLegacy if {@code false}. 134 */ refactorDiscoveryManager()135 public boolean refactorDiscoveryManager() { 136 synchronized (mDeviceConfigLock) { 137 return mRefactorDiscoveryManager; 138 } 139 } 140 141 /** 142 * @return {@code true} if enableBLE() is called during NearbyService init time. 143 */ enableBleInInit()144 public boolean enableBleInInit() { 145 synchronized (mDeviceConfigLock) { 146 return mEnableBleInInit; 147 } 148 } 149 150 private class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener { start()151 public void start() { 152 DeviceConfig.addOnPropertiesChangedListener(getNamespace(), 153 Executors.newSingleThreadExecutor(), this); 154 onPropertiesChanged(DeviceConfig.getProperties(getNamespace())); 155 } 156 157 @Override onPropertiesChanged(@onNull DeviceConfig.Properties properties)158 public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { 159 synchronized (mDeviceConfigLock) { 160 mEnablePresenceBroadcastLegacy = getDeviceConfigBoolean( 161 NEARBY_ENABLE_PRESENCE_BROADCAST_LEGACY, false /* defaultValue */); 162 mNanoAppMinVersion = getDeviceConfigInt( 163 NEARBY_MAINLINE_NANO_APP_MIN_VERSION, 0 /* defaultValue */); 164 mSupportTestApp = !IS_USER_BUILD && getDeviceConfigBoolean( 165 NEARBY_SUPPORT_TEST_APP, false /* defaultValue */); 166 mRefactorDiscoveryManager = getDeviceConfigBoolean( 167 NEARBY_REFACTOR_DISCOVERY_MANAGER, false /* defaultValue */); 168 mEnableBleInInit = getDeviceConfigBoolean( 169 NEARBY_ENABLE_BLE_IN_INIT, true /* defaultValue */); 170 } 171 } 172 } 173 } 174