OSDN Git Service

Add "Use open Wi-Fi automatically" setting.
authorAmin Shaikh <ashaikh@google.com>
Thu, 2 Feb 2017 23:47:53 +0000 (15:47 -0800)
committerAmin Shaikh <ashaikh@google.com>
Thu, 16 Mar 2017 23:54:20 +0000 (16:54 -0700)
- Add toggle to ConfigureWifiSettings for "Use open Wi-Fi automatically"
- Start ACTION_CUSTOM_ENABLE activity and handle result to set the
USE_OPEN_WIFI_PACKAGE setting.

Bug: 34773276
Test: make
Change-Id: I602e271d5113e415d290468548e35059bd45d8b8

res/values/strings.xml
res/xml/wifi_configure_settings.xml
src/com/android/settings/wifi/ConfigureWifiSettings.java
src/com/android/settings/wifi/UseOpenWifiPreferenceController.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/wifi/UseOpenWifiPreferenceControllerTest.java [new file with mode: 0644]

index bff3170..d6bd75f 100644 (file)
     <!-- Checkbox title for option to notify user when open networks are nearby -->
     <string name="wifi_notify_open_networks">Open network notification</string>
     <!-- Checkbox summary for option to notify user when open networks are nearby-->
-    <string name="wifi_notify_open_networks_summary">Notify whenever a high quality open network is available</string>
+    <string name="wifi_notify_open_networks_summary">Notify when a high\u2011quality open network is available that may require sign\u2011in</string>
     <!-- Checkbox title for option to enable Wi-Fi when saved networks are nearby -->
     <string name="wifi_wakeup">Turn Wi\u2011Fi back on</string>
-    <!-- Checkbox summary for option to enable Wi-Fi when saved networks are nearby-->
-    <string name="wifi_wakeup_summary">Automatically turn on Wi\u2011Fi near saved networks</string>
+    <!-- Checkbox summary for option to enable Wi-Fi when high quality saved networks are nearby-->
+    <string name="wifi_wakeup_summary">Automatically turn on Wi\u2011Fi near high\u2011quality saved networks</string>
     <!-- Checkbox title for option to toggle poor network detection -->
     <string name="wifi_poor_network_detection">Avoid poor connections</string>
     <!-- Checkbox summary for option to toggle poor network detection -->
     <string name="wifi_poor_network_detection_summary">Don\u2019t use a Wi\u2011Fi network unless it has a good Internet connection</string>
     <!-- Checkbox summary for option to toggle poor network detection [CHAR LIMIT=60] -->
     <string name="wifi_avoid_poor_network_detection_summary">Only use networks that have a good Internet connection</string>
-
+    <!-- Checkbox title for option to connect to open Wi-Fi automatically [CHAR LIMIT=40] -->
+    <string name="use_open_wifi_automatically_title">Connect to open networks</string>
+    <!-- Checkbox summary for option to connect to open Wi-Fi automatically  [CHAR LIMIT=100] -->
+    <string name="use_open_wifi_automatically_summary">Automatically connect to high\u2011quality open networks </string>
     <!-- Preference title for option to install certificates -->
     <string name="wifi_install_credentials">Install certificates</string>
     <!-- Message to describe "Wi-Fi scan always available feature" when Wi-Fi is off. The
index 8e51009..fa5239d 100644 (file)
             android:summary="@string/wifi_wakeup_summary" />
 
     <SwitchPreference
+        android:key="use_open_wifi_automatically"
+        android:icon="@drawable/ic_vpn_key"
+        android:title="@string/use_open_wifi_automatically_title"
+        android:summary="@string/use_open_wifi_automatically_summary" />
+
+    <SwitchPreference
             android:key="notify_open_networks"
             android:title="@string/wifi_notify_open_networks"
             android:icon="@drawable/ic_settings_notifications"
             android:summary="@string/wifi_notify_open_networks_summary" />
 
     <SwitchPreference
-            android:key="wifi_cellular_data_fallback"
-            android:title="@string/wifi_cellular_data_fallback_title"
-            android:summary="@string/wifi_cellular_data_fallback_summary"/>
+        android:key="wifi_cellular_data_fallback"
+        android:title="@string/wifi_cellular_data_fallback_title"
+        android:summary="@string/wifi_cellular_data_fallback_summary"/>
 
     <ListPreference
             android:key="sleep_policy"
index 78e869b..af80fd4 100644 (file)
@@ -19,6 +19,7 @@ import static android.content.Context.NETWORK_SCORE_SERVICE;
 import static android.content.Context.WIFI_SERVICE;
 
 import android.content.Context;
+import android.content.Intent;
 import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
 import android.provider.SearchIndexableResource;
@@ -43,7 +44,7 @@ public class ConfigureWifiSettings extends DashboardFragment {
 
     private static final String TAG = "ConfigureWifiSettings";
 
-    private WifiManager mWifiManager;
+    private UseOpenWifiPreferenceController mUseOpenWifiPreferenceController;
 
     @Override
     public int getMetricsCategory() {
@@ -58,7 +59,8 @@ public class ConfigureWifiSettings extends DashboardFragment {
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        mProgressiveDisclosureMixin.setTileLimit(2);
+        mProgressiveDisclosureMixin.setTileLimit(
+            mUseOpenWifiPreferenceController.isAvailable() ? 3 : 2);
         ((SettingsActivity) getActivity()).setDisplaySearchMenu(true);
     }
 
@@ -69,23 +71,35 @@ public class ConfigureWifiSettings extends DashboardFragment {
 
     @Override
     protected List<PreferenceController> getPreferenceControllers(Context context) {
-        mWifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
+        final NetworkScoreManagerWrapper networkScoreManagerWrapper =
+                new NetworkScoreManagerWrapper(context.getSystemService(NetworkScoreManager.class));
+        mUseOpenWifiPreferenceController = new UseOpenWifiPreferenceController(context, this,
+                networkScoreManagerWrapper, getLifecycle());
+        final WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
         final List<PreferenceController> controllers = new ArrayList<>();
-        controllers.add(new WifiInfoPreferenceController(context, getLifecycle(), mWifiManager));
-        controllers.add(new CellularFallbackPreferenceController(context));
-        controllers.add(new NotifyOpenNetworksPreferenceController(context, getLifecycle()));
         controllers.add(new WifiWakeupPreferenceController(context, getLifecycle()));
         controllers.add(new NetworkScorerPickerPreferenceController(context,
-                new NetworkScoreManagerWrapper(
-                        (NetworkScoreManager) getSystemService(NETWORK_SCORE_SERVICE))));
+                networkScoreManagerWrapper));
+        controllers.add(new NotifyOpenNetworksPreferenceController(context, getLifecycle()));
+        controllers.add(mUseOpenWifiPreferenceController);
         controllers.add(new WifiSleepPolicyPreferenceController(context));
-        controllers.add(new WifiP2pPreferenceController(context, getLifecycle(), mWifiManager));
+        controllers.add(new WifiInfoPreferenceController(context, getLifecycle(), wifiManager));
+        controllers.add(new CellularFallbackPreferenceController(context));
+        controllers.add(new WifiP2pPreferenceController(context, getLifecycle(), wifiManager));
         controllers.add(new WifiCallingPreferenceController(context));
         controllers.add(new WpsPreferenceController(
-                context, getLifecycle(), mWifiManager, getFragmentManager()));
+                context, getLifecycle(), wifiManager, getFragmentManager()));
         return controllers;
     }
 
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (mUseOpenWifiPreferenceController == null ||
+                !mUseOpenWifiPreferenceController.onActivityResult(requestCode, resultCode)) {
+            super.onActivityResult(requestCode, resultCode, data);
+        }
+    }
+
     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
diff --git a/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java b/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java
new file mode 100644 (file)
index 0000000..09f5e92
--- /dev/null
@@ -0,0 +1,165 @@
+package com.android.settings.wifi;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.net.NetworkScoreManager;
+
+import android.net.NetworkScorerAppData;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settings.network.NetworkScoreManagerWrapper;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+/**
+ * {@link PreferenceController} that controls whether a user wants to enable the "use open networks
+ * automatically" feature provider by the current network recommendation provider.
+ */
+public class UseOpenWifiPreferenceController extends PreferenceController
+        implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+    private static final String KEY_USE_OPEN_WIFI_AUTOMATICALLY = "use_open_wifi_automatically";
+    @VisibleForTesting static final int REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY = 400;
+
+    private final ContentResolver mContentResolver;
+    private final Fragment mFragment;
+    private final NetworkScoreManagerWrapper mNetworkScoreManagerWrapper;
+    private final SettingObserver mSettingObserver;
+
+    private Preference mPreference;
+    private ComponentName mEnableUseWifiComponentName;
+
+    public UseOpenWifiPreferenceController(Context context, Fragment fragment,
+            NetworkScoreManagerWrapper networkScoreManagerWrapper, Lifecycle lifecycle) {
+        super(context);
+        mContentResolver = context.getContentResolver();
+        mFragment = fragment;
+        mNetworkScoreManagerWrapper = networkScoreManagerWrapper;
+        mSettingObserver = new SettingObserver();
+        updateEnableUseWifiComponentName();
+        lifecycle.addObserver(this);
+    }
+
+    private void updateEnableUseWifiComponentName() {
+        NetworkScorerAppData appData = mNetworkScoreManagerWrapper.getActiveScorer();
+        mEnableUseWifiComponentName =
+                appData == null ? null : appData.getEnableUseOpenWifiActivity();
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(KEY_USE_OPEN_WIFI_AUTOMATICALLY);
+    }
+
+    @Override
+    public void onResume() {
+        mSettingObserver.register(mContentResolver);
+    }
+
+    @Override
+    public void onPause() {
+        mSettingObserver.unregister(mContentResolver);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return mEnableUseWifiComponentName != null;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_USE_OPEN_WIFI_AUTOMATICALLY;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        if (!(preference instanceof SwitchPreference)) {
+            return;
+        }
+        final SwitchPreference useOpenWifiPreference = (SwitchPreference) preference;
+        useOpenWifiPreference.setVisible(isAvailable());
+        useOpenWifiPreference.setChecked(isSettingEnabled());
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (!TextUtils.equals(preference.getKey(), KEY_USE_OPEN_WIFI_AUTOMATICALLY)
+                || !isAvailable()) {
+            return false;
+        }
+
+        if (isSettingEnabled()) {
+            Settings.Global.putString(mContentResolver,
+                    Settings.Global.USE_OPEN_WIFI_PACKAGE, "");
+            return true;
+        }
+
+        Intent intent = new Intent(NetworkScoreManager.ACTION_CUSTOM_ENABLE);
+        intent.setComponent(mEnableUseWifiComponentName);
+        mFragment.startActivityForResult(intent, REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY);
+        return false; // Updating state is done in onActivityResult.
+    }
+
+    private boolean isSettingEnabled() {
+        String enabledUseOpenWifiPackage = Settings.Global.getString(mContentResolver,
+                Settings.Global.USE_OPEN_WIFI_PACKAGE);
+        String currentUseOpenWifiPackage = mEnableUseWifiComponentName == null
+                ? null : mEnableUseWifiComponentName.getPackageName();
+        return TextUtils.equals(enabledUseOpenWifiPackage, currentUseOpenWifiPackage);
+    }
+
+    public boolean onActivityResult(int requestCode, int resultCode) {
+        if (requestCode != REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY) {
+            return false;
+        }
+
+        if (resultCode == Activity.RESULT_OK) {
+            Settings.Global.putString(mContentResolver, Settings.Global.USE_OPEN_WIFI_PACKAGE,
+                    mEnableUseWifiComponentName.getPackageName());
+        }
+        return true;
+    }
+
+    class SettingObserver extends ContentObserver {
+        private final Uri NETWORK_RECOMMENDATIONS_ENABLED_URI =
+                Settings.Global.getUriFor(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED);
+
+        public SettingObserver() {
+            super(new Handler(Looper.getMainLooper()));
+        }
+
+        public void register(ContentResolver cr) {
+            cr.registerContentObserver(NETWORK_RECOMMENDATIONS_ENABLED_URI, false, this);
+            onChange(true /* selfChange */, NETWORK_RECOMMENDATIONS_ENABLED_URI);
+        }
+
+        public void unregister(ContentResolver cr) {
+            cr.unregisterContentObserver(this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            if (NETWORK_RECOMMENDATIONS_ENABLED_URI.equals(uri)) {
+                updateEnableUseWifiComponentName();
+                updateState(mPreference);
+            }
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/UseOpenWifiPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/UseOpenWifiPreferenceControllerTest.java
new file mode 100644 (file)
index 0000000..aa89464
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2017 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.settings.wifi;
+
+import static android.provider.Settings.Global.USE_OPEN_WIFI_PACKAGE;
+import static com.android.settings.wifi.UseOpenWifiPreferenceController.REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.NetworkScoreManager;
+import android.net.NetworkScorerAppData;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.network.NetworkScoreManagerWrapper;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class UseOpenWifiPreferenceControllerTest {
+    private static ComponentName ENABLE_ACTIVITY_COMPONENT = new ComponentName("package", "activityClass");
+    private static NetworkScorerAppData APP_DATA =
+            new NetworkScorerAppData(0, null, null, ENABLE_ACTIVITY_COMPONENT);
+    private static NetworkScorerAppData APP_DATA_NO_ACTIVITY =
+            new NetworkScorerAppData(0, null, null, null);
+
+    @Mock private Lifecycle mLifecycle;
+    @Mock private Fragment mFragment;
+    @Mock private NetworkScoreManagerWrapper mNetworkScoreManagerWrapper;
+    @Captor private ArgumentCaptor<Intent> mIntentCaptor;
+    private Context mContext;
+    private UseOpenWifiPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application;
+    }
+
+    private void createController() {
+        mController = new UseOpenWifiPreferenceController(
+                mContext, mFragment, mNetworkScoreManagerWrapper, mLifecycle);
+    }
+
+    @Test
+    public void testIsAvailable_noScorer() {
+        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(null);
+
+        createController();
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void testIsAvailable_noEnableActivity() {
+        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(APP_DATA_NO_ACTIVITY);
+
+        createController();
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void testIsAvailable_enableActivityExists() {
+        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(APP_DATA);
+
+        createController();
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void onPreferenceChange_nonMatchingKey_shouldDoNothing() {
+        createController();
+
+        final SwitchPreference pref = new SwitchPreference(mContext);
+
+        assertThat(mController.onPreferenceChange(pref, null)).isFalse();
+    }
+
+    @Test
+    public void onPreferenceChange_notAvailable_shouldDoNothing() {
+        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(APP_DATA_NO_ACTIVITY);
+
+        createController();
+
+        final Preference pref = new Preference(mContext);
+        pref.setKey(mController.getPreferenceKey());
+
+        assertThat(mController.onPreferenceChange(pref, null)).isFalse();
+    }
+
+    @Test
+    public void onPreferenceChange_matchingKeyAndAvailable_enableShouldStartEnableActivity() {
+        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(APP_DATA);
+        createController();
+
+        final SwitchPreference pref = new SwitchPreference(mContext);
+        pref.setKey(mController.getPreferenceKey());
+
+        assertThat(mController.onPreferenceChange(pref, null)).isFalse();
+        verify(mFragment).startActivityForResult(mIntentCaptor.capture(),
+                eq(REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY));
+        Intent activityIntent = mIntentCaptor.getValue();
+        assertThat(activityIntent.getComponent()).isEqualTo(ENABLE_ACTIVITY_COMPONENT);
+        assertThat(activityIntent.getAction()).isEqualTo(NetworkScoreManager.ACTION_CUSTOM_ENABLE);
+    }
+
+    @Test
+    public void onPreferenceChange_matchingKeyAndAvailable_disableShouldUpdateSetting() {
+        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(APP_DATA);
+        Settings.Global.putString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE,
+                ENABLE_ACTIVITY_COMPONENT.getPackageName());
+
+        createController();
+
+        final SwitchPreference pref = new SwitchPreference(mContext);
+        pref.setKey(mController.getPreferenceKey());
+
+        assertThat(mController.onPreferenceChange(pref, null)).isTrue();
+        assertThat(Settings.Global.getString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE))
+                .isEqualTo("");
+    }
+
+    @Test
+    public void onActivityResult_nonmatchingRequestCode_shouldDoNothing() {
+        createController();
+
+        assertThat(mController.onActivityResult(234 /* requestCode */ , Activity.RESULT_OK))
+                .isEqualTo(false);
+        assertThat(Settings.Global.getString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE))
+                .isNull();
+    }
+
+    @Test
+    public void onActivityResult_matchingRequestCode_nonOkResult_shouldDoNothing() {
+        createController();
+
+        assertThat(mController
+                .onActivityResult(REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY, Activity.RESULT_CANCELED))
+                .isEqualTo(true);
+        assertThat(Settings.Global.getString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE))
+                .isNull();
+    }
+
+    @Test
+    public void onActivityResult_matchingRequestCode_okResult_updatesSetting() {
+        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(APP_DATA);
+        createController();
+
+        assertThat(mController
+                .onActivityResult(REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY, Activity.RESULT_OK))
+                .isEqualTo(true);
+        assertThat(Settings.Global.getString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE))
+                .isEqualTo(ENABLE_ACTIVITY_COMPONENT.getPackageName());
+    }
+
+    @Test
+    public void updateState_preferenceSetCheckedAndSetVisibleWhenSettingsAreEnabled() {
+        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(APP_DATA);
+        createController();
+
+        final SwitchPreference preference = mock(SwitchPreference.class);
+        Settings.Global.putString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE,
+                ENABLE_ACTIVITY_COMPONENT.getPackageName());
+
+        mController.updateState(preference);
+
+        verify(preference).setVisible(true);
+        verify(preference).setChecked(true);
+    }
+
+    @Test
+    public void updateState_preferenceSetCheckedAndSetVisibleWhenSettingsAreDisabled() {
+        final SwitchPreference preference = mock(SwitchPreference.class);
+        Settings.Global.putString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE, "");
+        createController();
+
+        mController.updateState(preference);
+
+        verify(preference).setVisible(false);
+        verify(preference).setChecked(false);
+    }
+}