1 /* 2 * Copyright (C) 2020 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 package com.google.android.utils.chre; 17 18 import android.app.Instrumentation; 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.location.LocationManager; 24 import android.os.UserHandle; 25 26 import androidx.test.InstrumentationRegistry; 27 28 import org.junit.Assert; 29 30 import java.util.concurrent.CountDownLatch; 31 import java.util.concurrent.TimeUnit; 32 33 /** 34 * A class to get or set settings parameters. 35 */ 36 public class SettingsUtil { 37 private final Context mContext; 38 39 private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation(); 40 41 private final LocationManager mLocationManager; 42 43 public class LocationUpdateListener { 44 public CountDownLatch mLocationLatch = new CountDownLatch(1); 45 46 public BroadcastReceiver mLocationSettingReceiver = new BroadcastReceiver() { 47 @Override 48 public void onReceive(Context context, Intent intent) { 49 if (LocationManager.MODE_CHANGED_ACTION.equals(intent.getAction())) { 50 mLocationLatch.countDown(); 51 } 52 } 53 }; 54 } 55 56 private class AirplaneModeListener { 57 protected CountDownLatch mAirplaneModeLatch = new CountDownLatch(1); 58 59 protected BroadcastReceiver mAirplaneModeReceiver = new BroadcastReceiver() { 60 @Override 61 public void onReceive(Context context, Intent intent) { 62 if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) { 63 mAirplaneModeLatch.countDown(); 64 } 65 } 66 }; 67 } 68 SettingsUtil(Context context)69 public SettingsUtil(Context context) { 70 mContext = context; 71 mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 72 Assert.assertTrue(mLocationManager != null); 73 } 74 75 /** 76 * @param enable true to enable always WiFi scanning. 77 */ setWifiScanningSettings(boolean enable)78 public void setWifiScanningSettings(boolean enable) { 79 String value = enable ? "1" : "0"; 80 ChreTestUtil.executeShellCommand( 81 mInstrumentation, "settings put global wifi_scan_always_enabled " + value); 82 83 Assert.assertTrue(isWifiScanningAlwaysEnabled() == enable); 84 } 85 86 /** 87 * @param enable true to enable WiFi service. 88 */ setWifi(boolean enable)89 public void setWifi(boolean enable) { 90 String value = enable ? "enable" : "disable"; 91 ChreTestUtil.executeShellCommand(mInstrumentation, "svc wifi " + value); 92 93 Assert.assertTrue(isWifiEnabled() == enable); 94 } 95 96 /** 97 * @return true if the WiFi scanning is always enabled. 98 */ isWifiScanningAlwaysEnabled()99 public boolean isWifiScanningAlwaysEnabled() { 100 String out = ChreTestUtil.executeShellCommand( 101 mInstrumentation, "settings get global wifi_scan_always_enabled"); 102 return ChreTestUtil.convertToIntegerOrFail(out) > 0; 103 } 104 105 /** 106 * @return true if the WiFi service is enabled. 107 */ isWifiEnabled()108 public boolean isWifiEnabled() { 109 String out = ChreTestUtil.executeShellCommand( 110 mInstrumentation, "settings get global wifi_on"); 111 return ChreTestUtil.convertToIntegerOrFail(out) > 0; 112 } 113 114 /** 115 * Sets the location mode on the device. 116 * @param enable True to enable location, false to disable it. 117 * @param timeoutSeconds The maximum amount of time in seconds to wait. 118 */ setLocationMode(boolean enable, long timeoutSeconds)119 public void setLocationMode(boolean enable, long timeoutSeconds) throws InterruptedException { 120 if (isLocationEnabled() != enable) { 121 LocationUpdateListener listener = new LocationUpdateListener(); 122 123 mContext.registerReceiver( 124 listener.mLocationSettingReceiver, 125 new IntentFilter(LocationManager.MODE_CHANGED_ACTION)); 126 mLocationManager.setLocationEnabledForUser(enable, UserHandle.CURRENT); 127 128 boolean success = listener.mLocationLatch.await(timeoutSeconds, TimeUnit.SECONDS); 129 Assert.assertTrue("Timeout waiting for signal: set location mode", success); 130 131 // Wait 1 additional second to make sure setting gets propagated to CHRE 132 Thread.sleep(1000); 133 134 Assert.assertTrue(isLocationEnabled() == enable); 135 136 mContext.unregisterReceiver(listener.mLocationSettingReceiver); 137 } 138 } 139 140 /** 141 * @return True if location is enabled. 142 */ isLocationEnabled()143 public boolean isLocationEnabled() { 144 return mLocationManager.isLocationEnabledForUser(UserHandle.CURRENT); 145 } 146 147 /** 148 * Sets the bluetooth mode to be on or off 149 * 150 * @param enable if true, turn bluetooth on; otherwise, turn bluetooth off 151 */ setBluetooth(boolean enable)152 public void setBluetooth(boolean enable) { 153 String value = enable ? "enable" : "disable"; 154 ChreTestUtil.executeShellCommand(mInstrumentation, "svc bluetooth " + value); 155 } 156 157 /** 158 * @param enable true to enable always bluetooth scanning. 159 */ setBluetoothScanningSettings(boolean enable)160 public void setBluetoothScanningSettings(boolean enable) { 161 String value = enable ? "1" : "0"; 162 ChreTestUtil.executeShellCommand( 163 mInstrumentation, "settings put global ble_scan_always_enabled " + value); 164 } 165 166 /** 167 * @return true if bluetooth is enabled, false otherwise 168 */ isBluetoothEnabled()169 public boolean isBluetoothEnabled() { 170 String out = ChreTestUtil.executeShellCommand( 171 mInstrumentation, "settings get global bluetooth_on"); 172 return ChreTestUtil.convertToIntegerOrFail(out) == 1; 173 } 174 175 /** 176 * @return true if the bluetooth scanning is always enabled. 177 */ isBluetoothScanningAlwaysEnabled()178 public boolean isBluetoothScanningAlwaysEnabled() { 179 String out = ChreTestUtil.executeShellCommand( 180 mInstrumentation, "settings get global ble_scan_always_enabled"); 181 182 // by default, this setting returns null, which is equivalent to 0 or disabled 183 return ChreTestUtil.convertToIntegerOrReturnZero(out) > 0; 184 } 185 186 /** 187 * Sets the airplane mode on the device. 188 * @param enable True to enable airplane mode, false to disable it. 189 */ setAirplaneMode(boolean enable)190 public void setAirplaneMode(boolean enable) throws InterruptedException { 191 if (isAirplaneModeOn() != enable) { 192 AirplaneModeListener listener = new AirplaneModeListener(); 193 mContext.registerReceiver( 194 listener.mAirplaneModeReceiver, 195 new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)); 196 197 String value = enable ? "enable" : "disable"; 198 ChreTestUtil.executeShellCommand( 199 mInstrumentation, "cmd connectivity airplane-mode " + value); 200 201 boolean success = listener.mAirplaneModeLatch.await(10, TimeUnit.SECONDS); 202 Assert.assertTrue("Timeout waiting for signal: set airplane mode", success); 203 // Wait 1 additional second to make sure setting gets propagated to CHRE 204 Thread.sleep(1000); 205 Assert.assertTrue(isAirplaneModeOn() == enable); 206 mContext.unregisterReceiver(listener.mAirplaneModeReceiver); 207 } 208 } 209 210 /** 211 * @return true if the airplane mode is currently enabled. 212 */ isAirplaneModeOn()213 public boolean isAirplaneModeOn() { 214 String out = ChreTestUtil.executeShellCommand( 215 mInstrumentation, "settings get global airplane_mode_on"); 216 return ChreTestUtil.convertToIntegerOrFail(out) > 0; 217 } 218 } 219