Update auto wi-fi to prompt user for permissions

This CL makes it so that auto wi-fi will correctly prompt users
to enable the correct permissions before allowing them to turn
on the setting. Additionally it provides users with important
information regarding each setting.

Bug: 67070896
Test: Robotests
Change-Id: Ieddfa421be6e45ce69f3d6048ae051a7e3ce4c76
diff --git a/res/drawable/ic_info_outline_24dp.xml b/res/drawable/ic_info_outline_24dp.xml
new file mode 100644
index 0000000..d1f27ab
--- /dev/null
+++ b/res/drawable/ic_info_outline_24dp.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorSecondary">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,17L12,17c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1l0,0c-0.55,0 -1,0.45 -1,1v4C11,16.55 11.45,17 12,17z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,2c-5.52,0 -10,4.48 -10,10s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,9.1L12,9.1c0.61,0 1.1,-0.49 1.1,-1.1l0,0c0,-0.61 -0.49,-1.1 -1.1,-1.1l0,0c-0.61,0 -1.1,0.49 -1.1,1.1l0,0C10.9,8.61 11.39,9.1 12,9.1z"/>
+</vector>
diff --git a/res/layout/wifi_settings_scanning_required_view.xml b/res/layout/wifi_settings_scanning_required_view.xml
new file mode 100644
index 0000000..8dad9f4
--- /dev/null
+++ b/res/layout/wifi_settings_scanning_required_view.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="24dp"
+        android:layout_marginRight="24dp"
+        android:layout_marginTop="8dp"
+        android:text="@string/wifi_settings_scanning_required_summary"
+        style="@style/TextAppearance.AppCompat.Subhead"/>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="top">
+
+        <ImageView
+            android:src="@drawable/ic_info_outline_24dp"
+            android:maxHeight="24dp"
+            android:maxWidth="24dp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="2dp"
+            android:layout_marginTop="4dp"
+            android:layout_marginLeft="24dp"
+            android:adjustViewBounds="true"/>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="8dp"
+            android:padding="8dp"
+            android:text="@string/wifi_settings_scanning_required_info"
+            android:textAppearance="?android:attr/textAppearanceSmall"/>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2857e6d..b3ae59f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1916,9 +1916,11 @@
     <!-- Wi-Fi settings dialog. Summary text describing why we need Wi-Fi scanning on. [CHAR LIMIT=NONE]-->
     <string name="wifi_settings_scanning_required_summary">To turn on Wi\u2011Fi automatically, you first need to turn on Wi\u2011Fi scanning.</string>
     <!-- Wi-Fi settings dialog. Informational text describing what Wi-Fi scanning does. [CHAR LIMIT=NONE]-->
-    <string name="wifi_settings_scanning_required_info">Wi\2011Fi scanning allows apps and services to scan for Wi\u2011Fi networks at any time, even when Wi\u2011Fi is off. This can be used, for example, to improve location\u2011based features and services.</string>
+    <string name="wifi_settings_scanning_required_info">Wi\u2011Fi scanning allows apps and services to scan for Wi\u2011Fi networks at any time, even when Wi\u2011Fi is off. This can be used, for example, to improve location\u2011based features and services.</string>
     <!-- Wi-Fi settings dialog. Text for the button that takes users to a help article about Wi-Fi scanning. [CHAR LIMIT = 20]-->
     <string name="wifi_settings_scanning_required_turn_on">Turn on</string>
+    <!-- Wi-Fi settings dialog. Text to show in toast for when user turns on wifi scanning. [CHAR LIMIT=NONE] -->
+    <string name="wifi_settings_scanning_required_enabled">Wi\u2011Fi scanning turned on</string>
 
     <!-- Dialog for Access Points --> <skip />
     <!-- Label to show/hide advanced options [CHAR LIMIT=40] -->
diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java
index 0938f67..96b2d03 100644
--- a/src/com/android/settings/wifi/ConfigureWifiSettings.java
+++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java
@@ -41,6 +41,7 @@
     private static final String TAG = "ConfigureWifiSettings";
 
     public static final String KEY_IP_ADDRESS = "current_ip_address";
+    public static final int WIFI_WAKEUP_REQUEST_CODE = 600;
 
     private WifiWakeupPreferenceController mWifiWakeupPreferenceController;
     private UseOpenWifiPreferenceController mUseOpenWifiPreferenceController;
@@ -71,7 +72,7 @@
 
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        mWifiWakeupPreferenceController = new WifiWakeupPreferenceController(context);
+        mWifiWakeupPreferenceController = new WifiWakeupPreferenceController(context, this);
         mUseOpenWifiPreferenceController = new UseOpenWifiPreferenceController(context, this,
                 getLifecycle());
         final WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
@@ -87,10 +88,16 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (mUseOpenWifiPreferenceController == null ||
-                !mUseOpenWifiPreferenceController.onActivityResult(requestCode, resultCode)) {
-            super.onActivityResult(requestCode, resultCode, data);
+        if (resultCode == WIFI_WAKEUP_REQUEST_CODE && mWifiWakeupPreferenceController != null) {
+            mWifiWakeupPreferenceController.onActivityResult(requestCode, resultCode);
+            return;
         }
+        if (resultCode == UseOpenWifiPreferenceController.REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY
+                && mUseOpenWifiPreferenceController == null) {
+            mUseOpenWifiPreferenceController.onActivityResult(requestCode, resultCode);
+            return;
+        }
+        super.onActivityResult(requestCode, resultCode, data);
     }
 
     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java b/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java
index 350f9d1..5a21bb7 100644
--- a/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java
+++ b/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java
@@ -36,9 +36,9 @@
 public class UseOpenWifiPreferenceController extends AbstractPreferenceController
         implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
         LifecycleObserver, OnResume, OnPause {
+    public static final int REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY = 400;
+
     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;
diff --git a/src/com/android/settings/wifi/WifiScanningRequiredFragment.java b/src/com/android/settings/wifi/WifiScanningRequiredFragment.java
new file mode 100644
index 0000000..e0b804a
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiScanningRequiredFragment.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 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 com.android.settings.wifi.ConfigureWifiSettings.WIFI_WAKEUP_REQUEST_CODE;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.widget.Toast;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class WifiScanningRequiredFragment extends InstrumentedDialogFragment implements
+        DialogInterface.OnClickListener {
+
+    public static WifiScanningRequiredFragment newInstance() {
+        WifiScanningRequiredFragment fragment = new WifiScanningRequiredFragment();
+        return fragment;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        return new AlertDialog.Builder(getContext())
+                .setTitle(R.string.wifi_settings_scanning_required_title)
+                .setView(R.layout.wifi_settings_scanning_required_view)
+                .setNeutralButton(R.string.do_disclosure_learn_more, this)
+                .setPositiveButton(R.string.wifi_settings_scanning_required_turn_on, this)
+                .setNegativeButton(R.string.cancel, null)
+                .create();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(b/67070896): add metric code
+        return 0;
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        Context context = getContext();
+        ContentResolver contentResolver = context.getContentResolver();
+        switch(which) {
+            case DialogInterface.BUTTON_POSITIVE:
+                Settings.Global.putInt(contentResolver,
+                        Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 1);
+                Toast.makeText(
+                        context,
+                        context.getString(R.string.wifi_settings_scanning_required_enabled),
+                        Toast.LENGTH_SHORT).show();
+                getTargetFragment().onActivityResult(
+                        getTargetRequestCode(),
+                        Activity.RESULT_OK,
+                        null);
+                break;
+            case DialogInterface.BUTTON_NEUTRAL:
+                openHelpPage();
+                break;
+            case DialogInterface.BUTTON_NEGATIVE:
+            default:
+                // do nothing
+        }
+    }
+
+    private void openHelpPage() {
+        // TODO(b/67070896): actually open help page on Pixel only
+    }
+}
diff --git a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
index 5a9f6ae..3eac471 100644
--- a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
@@ -16,8 +16,15 @@
 
 package com.android.settings.wifi;
 
+import static com.android.settings.wifi.ConfigureWifiSettings.WIFI_WAKEUP_REQUEST_CODE;
+
+import android.app.Fragment;
+import android.app.Service;
 import android.content.Context;
+import android.content.Intent;
+import android.location.LocationManager;
 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;
@@ -25,24 +32,37 @@
 
 import com.android.settings.R;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.utils.AnnotationSpan;
 import com.android.settingslib.core.AbstractPreferenceController;
 
 /**
  * {@link PreferenceControllerMixin} that controls whether the Wi-Fi Wakeup feature should be
  * enabled.
  */
-public class WifiWakeupPreferenceController extends AbstractPreferenceController
-        implements PreferenceControllerMixin {
+public class WifiWakeupPreferenceController extends AbstractPreferenceController {
 
+    private static final String TAG = "WifiWakeupPrefController";
     private static final String KEY_ENABLE_WIFI_WAKEUP = "enable_wifi_wakeup";
 
-    public WifiWakeupPreferenceController(Context context) {
+    private final Fragment mFragment;
+
+    @VisibleForTesting
+    SwitchPreference mPreference;
+    @VisibleForTesting
+    LocationManager mLocationManager;
+
+    public WifiWakeupPreferenceController(Context context, DashboardFragment fragment) {
         super(context);
+        mFragment = fragment;
+        mLocationManager = (LocationManager) context.getSystemService(Service.LOCATION_SERVICE);
     }
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
+        mPreference = (SwitchPreference) screen.findPreference(KEY_ENABLE_WIFI_WAKEUP);
+        updateState(mPreference);
     }
 
     @Override
@@ -58,9 +78,19 @@
         if (!(preference instanceof SwitchPreference)) {
             return false;
         }
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_WAKEUP_ENABLED,
-                ((SwitchPreference) preference).isChecked() ? 1 : 0);
+
+        if (!mLocationManager.isLocationEnabled()) {
+            final Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+            mFragment.startActivity(intent);
+        } else if (getWifiWakeupEnabled()) {
+            setWifiWakeupEnabled(false);
+        } else if (!getWifiScanningEnabled()) {
+            showScanningDialog();
+        } else {
+            setWifiWakeupEnabled(true);
+        }
+
+        updateState(mPreference);
         return true;
     }
 
@@ -76,17 +106,51 @@
         }
         final SwitchPreference enableWifiWakeup = (SwitchPreference) preference;
 
-        enableWifiWakeup.setChecked(Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1);
-
-        boolean wifiScanningEnabled = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1;
-        enableWifiWakeup.setEnabled(wifiScanningEnabled);
-
-        if (wifiScanningEnabled) {
-            enableWifiWakeup.setSummary(R.string.wifi_wakeup_summary);
+        enableWifiWakeup.setChecked(getWifiWakeupEnabled()
+                        && getWifiScanningEnabled()
+                        && mLocationManager.isLocationEnabled());
+        if (!mLocationManager.isLocationEnabled()) {
+            preference.setSummary(getNoLocationSummary());
         } else {
-            enableWifiWakeup.setSummary(R.string.wifi_wakeup_summary_scanning_disabled);
+            preference.setSummary(R.string.wifi_wakeup_summary);
         }
     }
+
+    @VisibleForTesting CharSequence getNoLocationSummary() {
+        AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo("link", null);
+        CharSequence locationText = mContext.getText(R.string.wifi_wakeup_summary_no_location);
+        return AnnotationSpan.linkify(locationText, linkInfo);
+    }
+
+    public void onActivityResult(int requestCode, int resultCode) {
+        if (requestCode != WIFI_WAKEUP_REQUEST_CODE) {
+            return;
+        }
+        if (mLocationManager.isLocationEnabled()) {
+            setWifiWakeupEnabled(true);
+        }
+        updateState(mPreference);
+    }
+
+    private boolean getWifiScanningEnabled() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1;
+    }
+
+    private void showScanningDialog() {
+        final WifiScanningRequiredFragment dialogFragment =
+                WifiScanningRequiredFragment.newInstance();
+        dialogFragment.setTargetFragment(mFragment, WIFI_WAKEUP_REQUEST_CODE /* requestCode */);
+        dialogFragment.show(mFragment.getFragmentManager(), TAG);
+    }
+
+    private boolean getWifiWakeupEnabled() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
+    }
+
+    private void setWifiWakeupEnabled(boolean enabled) {
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.WIFI_WAKEUP_ENABLED,
+                enabled ? 1 : 0);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiScanningRequiredFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/WifiScanningRequiredFragmentTest.java
new file mode 100644
index 0000000..f9d2176
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/WifiScanningRequiredFragmentTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 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 com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.app.Fragment;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.provider.Settings;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class WifiScanningRequiredFragmentTest {
+
+    private WifiScanningRequiredFragment mFragment;
+    private Context mContext;
+    private ContentResolver mResolver;
+    @Mock
+    Fragment mCallbackFragment;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mFragment = spy(WifiScanningRequiredFragment.newInstance());
+        mContext = RuntimeEnvironment.application;
+        mResolver = mContext.getContentResolver();
+
+        doReturn(mContext).when(mFragment).getContext();
+        mFragment.setTargetFragment(mCallbackFragment, 1000);
+        Settings.Global.putInt(mResolver, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+    }
+
+    @After
+    public void tearDown() {
+        SettingsShadowResources.reset();
+    }
+
+    @Test
+    public void onClick_positiveButtonSetsWifiScanningOn()
+            throws Settings.SettingNotFoundException {
+        mFragment.onClick(null, DialogInterface.BUTTON_POSITIVE);
+
+        assertThat(Settings.Global.getInt(mResolver, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE))
+                .isEqualTo(1);
+    }
+
+    @Test
+    public void onClick_positiveButtonCallsBackToActivity() {
+        mFragment.onClick(null, DialogInterface.BUTTON_POSITIVE);
+
+        verify(mCallbackFragment).onActivityResult(anyInt(), anyInt(), isNull());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
index 7bc51e9..d10b0e5 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
@@ -19,15 +19,20 @@
 import static android.provider.Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE;
 import static android.provider.Settings.Global.WIFI_WAKEUP_ENABLED;
 import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
+import android.app.Fragment;
 import android.content.Context;
+import android.location.LocationManager;
 import android.provider.Settings;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
 
 import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 
@@ -35,21 +40,34 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class WifiWakeupPreferenceControllerTest {
 
+    private static final String NO_LOCATION_STRING =
+            "Unavailable because location is turned off. Turn on location.";
     private Context mContext;
     private WifiWakeupPreferenceController mController;
+    @Mock
+    DashboardFragment mFragment;
+    @Mock
+    LocationManager mLocationManager;
+    @Mock
+    SwitchPreference mPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        mController = new WifiWakeupPreferenceController(mContext);
+        mController = new WifiWakeupPreferenceController(mContext, mFragment);
+        mController.mLocationManager = mLocationManager;
+        mController.mPreference = mPreference;
+
         Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 1);
+        doReturn(true).when(mLocationManager).isLocationEnabled();
     }
 
     @After
@@ -84,39 +102,72 @@
     }
 
     @Test
-    public void updateState_preferenceSetCheckedAndSetEnabledWhenWakeupSettingEnabled() {
+    public void updateState_preferenceSetCheckedWhenWakeupSettingEnabled() {
         final SwitchPreference preference = mock(SwitchPreference.class);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
 
         mController.updateState(preference);
 
         verify(preference).setChecked(true);
-        verify(preference).setEnabled(true);
         verify(preference).setSummary(R.string.wifi_wakeup_summary);
     }
 
     @Test
-    public void updateState_preferenceSetUncheckedAndSetEnabledWhenWakeupSettingDisabled() {
+    public void updateState_preferenceSetUncheckedWhenWakeupSettingDisabled() {
         final SwitchPreference preference = mock(SwitchPreference.class);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 0);
 
         mController.updateState(preference);
 
         verify(preference).setChecked(false);
-        verify(preference).setEnabled(true);
         verify(preference).setSummary(R.string.wifi_wakeup_summary);
     }
 
     @Test
-    public void updateState_preferenceSetUncheckedAndSetDisabledWhenWifiScanningDisabled() {
+    public void updateState_preferenceSetUncheckedWhenWifiScanningDisabled() {
         final SwitchPreference preference = mock(SwitchPreference.class);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 0);
 
         mController.updateState(preference);
 
-        verify(preference).setChecked(true);
-        verify(preference).setEnabled(false);
-        verify(preference).setSummary(R.string.wifi_wakeup_summary_scanning_disabled);
+        verify(preference).setChecked(false);
+    }
+
+    @Test
+    public void updateState_preferenceSetUncheckedWhenWakeupSettingEnabledNoLocation() {
+        final SwitchPreference preference = mock(SwitchPreference.class);
+        Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
+        doReturn(false).when(mLocationManager).isLocationEnabled();
+
+        mController.updateState(preference);
+
+        verify(preference).setChecked(false);
+        verify(preference).setSummary(mController.getNoLocationSummary());
+    }
+
+    @Test
+    public void updateState_preferenceSetUncheckedWhenWakeupSettingDisabledLocationEnabled() {
+        final SwitchPreference preference = mock(SwitchPreference.class);
+        Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 0);
+        doReturn(false).when(mLocationManager).isLocationEnabled();
+
+        mController.updateState(preference);
+
+        verify(preference).setChecked(false);
+        verify(preference).setSummary(mController.getNoLocationSummary());
+    }
+
+    @Test
+    public void updateState_preferenceSetUncheckedWhenWifiScanningDisabledLocationEnabled() {
+        final SwitchPreference preference = mock(SwitchPreference.class);
+        Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
+        Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+        doReturn(false).when(mLocationManager).isLocationEnabled();
+
+        mController.updateState(preference);
+
+        verify(preference).setChecked(false);
+        verify(preference).setSummary(mController.getNoLocationSummary());
     }
 }