/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wifi; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.os.Handler; import android.provider.Settings; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; /** * Note: This is a hack to provide backward compatibility with the * {@link Settings.Global#WIFI_SCAN_ALWAYS_AVAILABLE} @hide settings usage. We migrated storage * of the scan always available state from this setting to our internal storage, but need to support * the existing @hide users. * TODO(b/149954910): We should find a path to stop supporting this! */ public class WifiScanAlwaysAvailableSettingsCompatibility { private static final String TAG = "WifiScanAlwaysAvailableSettingsCompatibility"; /** * Copy of the settings string. Can't directly use the constant because it is @hide. */ @VisibleForTesting public static final String SETTINGS_GLOBAL_WIFI_SCAN_ALWAYS_AVAILABLE = "wifi_scan_always_enabled"; private final Context mContext; private final ContentResolver mContentResolver; private final Handler mHandler; private final WifiSettingsStore mWifiSettingsStore; private final ActiveModeWarden mActiveModeWarden; private final FrameworkFacade mFrameworkFacade; public WifiScanAlwaysAvailableSettingsCompatibility(Context context, Handler handler, WifiSettingsStore wifiSettingsStore, ActiveModeWarden activeModeWarden, FrameworkFacade frameworkFacade) { mContext = context; mHandler = handler; mWifiSettingsStore = wifiSettingsStore; mActiveModeWarden = activeModeWarden; mFrameworkFacade = frameworkFacade; // Cache the content resolver to ensure that we can detect self changes. mContentResolver = context.getContentResolver(); } /** * Register settings change observer. */ public void initialize() { ContentObserver contentObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { // Ignore any changes we triggered to avoid causing a loop. if (selfChange) return; boolean settingsIsAvailable = mFrameworkFacade.getIntegerSetting( mContentResolver, SETTINGS_GLOBAL_WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1; // Check if the new state is different from our current state. if (mWifiSettingsStore.isScanAlwaysAvailableToggleEnabled() != settingsIsAvailable) { Log.i(TAG, "settings changed, new value: " + settingsIsAvailable + ", triggering update"); mWifiSettingsStore.handleWifiScanAlwaysAvailableToggled(settingsIsAvailable); mActiveModeWarden.scanAlwaysModeChanged(); } } }; mContentResolver.registerContentObserver( Settings.Global.getUriFor(SETTINGS_GLOBAL_WIFI_SCAN_ALWAYS_AVAILABLE), false, contentObserver); } /** * Handle scan always available toggle from {@link android.net.wifi.WifiManager# * setScanAlwaysAvailable(boolean)} */ public void handleWifiScanAlwaysAvailableToggled(boolean isAvailable) { mFrameworkFacade.setIntegerSetting( mContentResolver, SETTINGS_GLOBAL_WIFI_SCAN_ALWAYS_AVAILABLE, isAvailable ? 1 : 0); } }