Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 203b923c authored by Phil Weaver's avatar Phil Weaver
Browse files

Settings reflect new a11y shortcut on lockscreen

Matching changes to the framework behavior. The
setting is on by default iff the user has agreed
to use the a11y shortcut.

Bug: 70944865
Test: Adding new test for this fragment that checks
this behavior

Change-Id: I7831f64cf3ec59c2d266340cc570227433a4febb
parent 68628c2e
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -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());
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
    <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

    <application>
        <uses-library android:name="android.test.runner" />
+141 −0
Original line number Diff line number Diff line
/*
 * 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<AccessibilitySettingsActivity> 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));
    }
}