diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index d3217832794..bc164ab5152 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -20,7 +20,9 @@ import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.database.ContentObserver;
import android.os.Bundle;
+import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
@@ -46,6 +48,12 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer
private Preference mServicePreference;
private SwitchPreference mOnLockScreenSwitchPreference;
+ private final ContentObserver mContentObserver = new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updatePreferences();
+ }
+ };
@Override
public int getMetricsCategory() {
@@ -77,6 +85,15 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer
public void onResume() {
super.onResume();
updatePreferences();
+ getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN),
+ false, mContentObserver);
+ }
+
+ @Override
+ public void onPause() {
+ getContentResolver().unregisterContentObserver(mContentObserver);
+ super.onPause();
}
@Override
@@ -120,8 +137,13 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer
boolean isEnabled = Settings.Secure
.getInt(cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 1) == 1;
mSwitchBar.setChecked(isEnabled);
- mOnLockScreenSwitchPreference.setChecked(Settings.Secure.getInt(
- cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, 0) == 1);
+ // The shortcut is enabled by default on the lock screen as long as the user has
+ // enabled the shortcut with the warning dialog
+ final int dialogShown = Settings.Secure.getInt(
+ cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
+ final boolean enabledFromLockScreen = Settings.Secure.getInt(
+ cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, dialogShown) == 1;
+ mOnLockScreenSwitchPreference.setChecked(enabledFromLockScreen);
// Only enable changing the service and lock screen behavior if the shortcut is on
mServicePreference.setEnabled(mToggleSwitch.isChecked());
mOnLockScreenSwitchPreference.setEnabled(mToggleSwitch.isChecked());
diff --git a/tests/unit/AndroidManifest.xml b/tests/unit/AndroidManifest.xml
index eccbac36486..05637534858 100644
--- a/tests/unit/AndroidManifest.xml
+++ b/tests/unit/AndroidManifest.xml
@@ -26,6 +26,7 @@
+
diff --git a/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java b/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
new file mode 100644
index 00000000000..886f4f0f004
--- /dev/null
+++ b/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.accessibility;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.collection.IsIn.oneOf;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static android.support.test.espresso.matcher.ViewMatchers.isChecked;
+import static android.support.test.espresso.matcher.ViewMatchers.isNotChecked;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static android.support.test.espresso.matcher.ViewMatchers.withParent;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.widget.CompoundButton;
+
+import com.android.settings.R;
+import com.android.settings.Settings.AccessibilitySettingsActivity;
+import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settings.core.SubSettingLauncher;
+
+import org.hamcrest.Matcher;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityShortcutPreferenceFragmentTest {
+ @Rule
+ public final ActivityTestRule mActivityRule =
+ new ActivityTestRule<>(AccessibilitySettingsActivity.class, true);
+
+ private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ private AccessibilityShortcutPreferenceFragment mAccessibilityShortcutPreferenceFragment;
+ private AccessibilitySettingsActivity mActivity;
+
+ @Before
+ public void setUp() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void lockScreenPreference_defaultBeforeDialogShown_isOff() {
+ setDialogShown(false);
+ setOnLockscreen(null);
+ startFragment();
+ assertLockscreenSwitchIsCheckedIs(false);
+ }
+
+ @Test
+ public void lockScreenPreference_setOnBeforeDialogShown_isOn() {
+ setDialogShown(false);
+ setOnLockscreen(true);
+ startFragment();
+ assertLockscreenSwitchIsCheckedIs(true);
+ }
+
+ @Test
+ public void lockScreenPreference_defaultAfterDialogShown_isOn() {
+ setDialogShown(true);
+ setOnLockscreen(null);
+ startFragment();
+ assertLockscreenSwitchIsCheckedIs(true);
+ }
+
+ @Test
+ public void lockScreenPreference_setOffAfterDialogShown_isOn() {
+ setDialogShown(true);
+ setOnLockscreen(false);
+ startFragment();
+ assertLockscreenSwitchIsCheckedIs(false);
+ }
+
+ private void startFragment() {
+ mInstrumentation.runOnMainSync(() -> {
+ new SubSettingLauncher(mActivity)
+ .setDestination(AccessibilityShortcutPreferenceFragment.class.getName())
+ .setArguments(new Bundle())
+ .setSourceMetricsCategory(
+ InstrumentedPreferenceFragment.METRICS_CATEGORY_UNKNOWN)
+ .launch();
+ });
+ }
+
+ private void setDialogShown(boolean shown) {
+ Settings.Secure.putInt(mActivity.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, shown ? 1 : 0);
+ }
+
+ private void setOnLockscreen(Boolean onLockscreen) {
+ if (onLockscreen == null) {
+ Settings.Secure.putString(mActivity.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, null);
+ } else {
+ Settings.Secure.putInt(mActivity.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, onLockscreen ? 1 : 0);
+ }
+ }
+
+ private void assertLockscreenSwitchIsCheckedIs(boolean isChecked) {
+ // Identify the switch by looking for a grandparent that has a descendent with the
+ // switch label. To disambiguate, make sure that grandparent doesn't also have a descendant
+ // with the title of the main switch
+ final String lockScreenSwitchTitle =
+ mActivity.getString(R.string.accessibility_shortcut_service_on_lock_screen_title);
+ final String mainSwitchTitle =
+ mActivity.getString(R.string.accessibility_service_master_switch_title);
+ Matcher isCheckedMatcher = (isChecked) ? isChecked() : isNotChecked();
+ Matcher hasLockScreenTitleDescendant = hasDescendant(withText(lockScreenSwitchTitle));
+ Matcher noMainSwitchTitleDescendant = not(hasDescendant(withText(mainSwitchTitle)));
+ onView(allOf(withParent(withParent(allOf(
+ hasLockScreenTitleDescendant, noMainSwitchTitleDescendant))),
+ instanceOf(CompoundButton.class))).check(matches(isCheckedMatcher));
+ }
+}