blob: d4764894125ac50859ca4c3bbed2b6efb2be6381 [file] [log] [blame]
package com.android.clockwork.wifi;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
/**
* Settings wrapper for WearWifiMediator.
*
* go/cw-wifi-settings-management-f
*/
public class WearWifiMediatorSettings {
private static final String TAG = "WearWifiMediator";
interface Listener {
void onWifiSettingChanged(String newWifiSetting);
void onInWifiSettingsMenuChanged(boolean inWifiSettingsMenu);
void onEnableWifiWhileChargingChanged(boolean enableWifiWhileCharging);
void onDisableWifiMediatorChanged(boolean disableWifiMediator);
void onHardwareLowPowerModeChanged(boolean inHardwareLowPowerMode);
void onWifiOnWhenProxyDisconnectedChanged(boolean wifiOnWhenProxyDisconnected);
}
/** valid values for this key: "on", "off", "off_airplane" */
static final String WIFI_SETTING_KEY = "clockwork_wifi_setting";
static final String WIFI_SETTING_ON = "on";
static final String WIFI_SETTING_OFF = "off";
static final String WIFI_SETTING_OFF_AIRPLANE = "off_airplane";
/** valid values for this key are 0 and 1 */
static final String IN_WIFI_SETTINGS_KEY = "clockwork_in_wifi_settings";
/**
* Dev Option which can be used to prevent WifiMediator from being affected by
* whether the device is charging or not. This makes it possible to debug WifiMediator
* with the device plugged in.
*/
static final String ENABLE_WIFI_WHEN_CHARGING_KEY = "cw_enable_wifi_when_charging";
/**
* Dev Option for disabling WifiMediator. Used for testing only.
*/
static final String DISABLE_WIFI_MEDIATOR_KEY = "cw_disable_wifimediator";
/**
* Hardware Low Power Mode causes WiFi to be disabled and prevents the user and all apps
* from re-enabling WiFi. This is used by device-specific software to prevent potential
* brownouts caused by the power spikes from the WiFi adapter during very low-power states.
*/
static final String HW_LOW_POWER_MODE_KEY = "wifi_hw_low_power_mode";
private final ContentResolver mContentResolver;
private final HashSet<Listener> mListeners = new HashSet<>();
private final SettingsObserver mSettingsObserver;
public WearWifiMediatorSettings(ContentResolver contentResolver) {
mContentResolver = contentResolver;
mSettingsObserver = new SettingsObserver(new Handler(Looper.getMainLooper()));
for (Uri uri : getObservedUris()) {
Log.d(TAG, "Registering content observer for " + uri);
mContentResolver.registerContentObserver(uri, false, mSettingsObserver);
}
}
@VisibleForTesting
SettingsObserver getSettingsObserver() {
return mSettingsObserver;
}
@VisibleForTesting
List<Uri> getObservedUris() {
ArrayList<Uri> uris = new ArrayList<>();
uris.add(Settings.System.getUriFor(WIFI_SETTING_KEY));
uris.add(Settings.System.getUriFor(IN_WIFI_SETTINGS_KEY));
uris.add(Settings.System.getUriFor(ENABLE_WIFI_WHEN_CHARGING_KEY));
uris.add(Settings.Global.getUriFor(DISABLE_WIFI_MEDIATOR_KEY));
uris.add(Settings.Global.getUriFor(HW_LOW_POWER_MODE_KEY));
uris.add(Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON));
uris.add(Settings.Global.getUriFor(Settings.Global.WIFI_ON_WHEN_PROXY_DISCONNECTED));
return uris;
}
public void addListener(Listener listener) {
mListeners.add(listener);
}
@VisibleForTesting
final class SettingsObserver extends ContentObserver {
public SettingsObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
Log.d(TAG, "onChange called");
if (uri.equals(Settings.System.getUriFor(WIFI_SETTING_KEY))) {
String newWifiSetting = getWifiSetting();
Log.d(TAG, "Wifi Setting changed to: " + newWifiSetting);
for (Listener listener : mListeners) {
listener.onWifiSettingChanged(newWifiSetting);
}
} else if (uri.equals(Settings.System.getUriFor(IN_WIFI_SETTINGS_KEY))) {
boolean inWifiSettings = getInWifiSettings();
Log.d(TAG, "In WiFi Settings Menu state changed: " + inWifiSettings);
for (Listener listener : mListeners) {
listener.onInWifiSettingsMenuChanged(inWifiSettings);
}
} else if (uri.equals(Settings.System.getUriFor(ENABLE_WIFI_WHEN_CHARGING_KEY))) {
boolean enableWhileCharging = getEnableWifiWhileCharging();
Log.d(TAG, "Enable WiFi while charging changed to: " + enableWhileCharging);
for (Listener listener : mListeners) {
listener.onEnableWifiWhileChargingChanged(getEnableWifiWhileCharging());
}
} else if (uri.equals(Settings.Global.getUriFor(DISABLE_WIFI_MEDIATOR_KEY))) {
boolean disableWifiMediator = getDisableWifiMediator();
Log.d(TAG, "Disable WifiMediator set to: " + disableWifiMediator);
for (Listener listener : mListeners) {
listener.onDisableWifiMediatorChanged(disableWifiMediator);
}
} else if (uri.equals(Settings.Global.getUriFor(HW_LOW_POWER_MODE_KEY))) {
boolean hardwareLowPowerMode = getHardwareLowPowerMode();
Log.d(TAG, "Hardware Low Power Mode changed to: " + hardwareLowPowerMode);
for (Listener listener : mListeners) {
listener.onHardwareLowPowerModeChanged(hardwareLowPowerMode);
}
} else if (uri.equals(Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON))) {
boolean isAirplaneModeOn = getIsInAirplaneMode();
Log.d(TAG, "Airplane Mode turned " + (isAirplaneModeOn ? "on" : "off"));
String oldWifiSetting = getWifiSetting();
String newWifiSetting = updateWifiSettingOnAirplaneModeChange(oldWifiSetting, isAirplaneModeOn);
if (!oldWifiSetting.equals(newWifiSetting)) {
for (Listener listener : mListeners) {
listener.onWifiSettingChanged(newWifiSetting);
}
}
} else if (uri.equals(Settings.Global.getUriFor(
Settings.Global.WIFI_ON_WHEN_PROXY_DISCONNECTED))) {
boolean wifiOnWhenProxyDisconnected = getWifiOnWhenProxyDisconnected();
Log.d(TAG, "Turn Wifi On After Proxy Disconnected changed to: "
+ (wifiOnWhenProxyDisconnected ? "true" : "false"));
for(Listener listener : mListeners) {
listener.onWifiOnWhenProxyDisconnectedChanged(wifiOnWhenProxyDisconnected);
}
}
}
}
public boolean getWifiOnWhenProxyDisconnected() {
return Settings.Global.getInt(mContentResolver,
Settings.Global.WIFI_ON_WHEN_PROXY_DISCONNECTED, 1) == 1;
}
public boolean getIsInAirplaneMode() {
return Settings.Global.getInt(
mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
}
public String getWifiSetting() {
String value = Settings.System.getString(mContentResolver, WIFI_SETTING_KEY);
if (value == null) {
value = WIFI_SETTING_ON;
}
return value;
}
public void putWifiSetting(String wifiSetting) {
Settings.System.putString(mContentResolver, WIFI_SETTING_KEY, wifiSetting);
}
public boolean getInWifiSettings() {
return Settings.System.getInt(mContentResolver, IN_WIFI_SETTINGS_KEY, 0) != 0;
}
public boolean getEnableWifiWhileCharging() {
return Settings.System.getInt(mContentResolver, ENABLE_WIFI_WHEN_CHARGING_KEY, 1) != 0;
}
public boolean getDisableWifiMediator() {
return Settings.Global.getInt(mContentResolver, DISABLE_WIFI_MEDIATOR_KEY, 0) != 0;
}
public boolean getHardwareLowPowerMode() {
return Settings.Global.getInt(mContentResolver, HW_LOW_POWER_MODE_KEY, 0) != 0;
}
public String updateWifiSettingOnAirplaneModeChange(String currentWifiSetting, boolean airplaneModeOn) {
String newSetting = currentWifiSetting;
if (airplaneModeOn) {
// when entering airplane mode, the WIFI_SETTING conversion should be:
// ON -> OFF
// OFF -> OFF_AIRPLANE
if (WIFI_SETTING_ON.equals(currentWifiSetting)) {
newSetting = WIFI_SETTING_OFF;
} else {
newSetting = WIFI_SETTING_OFF_AIRPLANE;
}
} else {
// when leaving airplane mode, the WIFI_SETTING conversion should be:
// ON -> ON
// OFF -> ON
// OFF_AIRPLANE -> OFF
if (WIFI_SETTING_OFF.equals(currentWifiSetting)) {
newSetting = WIFI_SETTING_ON;
} else if (WIFI_SETTING_OFF_AIRPLANE.equals(currentWifiSetting)) {
newSetting = WIFI_SETTING_OFF;
}
}
if (!newSetting.equals(currentWifiSetting)) {
putWifiSetting(newSetting);
}
return newSetting;
}
}