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

Commit 39e42bf9 authored by Roy Chou's avatar Roy Chou Committed by Android (Google) Code Review
Browse files

Merge "feat(onefingerpan): hide the one finger pan settings when window mode only" into main

parents 8d3d9757 acf98a6a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4814,6 +4814,8 @@
    <!-- Summary for accessibility magnification preference when one finger panning feature is turned off.
         The feature when disabled, allows user to move the magnification area by dragging two fingers instead of one. [CHAR LIMIT=60] -->
    <string name="accessibility_magnification_one_finger_panning_summary_off">Move the magnification area by dragging two fingers.</string>
    <!-- Summary for accessibility magnification preference when one finger panning feature is unavailable while partial-only capability. [CHAR LIMIT=none] -->
    <string name="accessibility_magnification_one_finger_panning_summary_unavailable">Unavailable while only magnifying part of the screen</string>
    <!-- Title for the accessibility preference screen to enable navigation bar screen magnification. [CHAR LIMIT=35] -->
    <string name="accessibility_screen_magnification_navbar_title">Magnify with shortcut</string>
    <!-- Summary for the accessibility magnification setting indicating both "Magnify with button" and "Magnify with triple-tap" are enabled [CHAR LIMIT=50] -->
+51 −9
Original line number Diff line number Diff line
@@ -21,27 +21,43 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.ON;

import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;

import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.TwoStatePreference;

import com.android.server.accessibility.Flags;
import com.android.settings.R;
import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;

public class MagnificationOneFingerPanningPreferenceController
        extends TogglePreferenceController {
        extends TogglePreferenceController implements LifecycleObserver, OnResume, OnPause {
    static final String PREF_KEY = Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;

    @Nullable
    private TwoStatePreference mSwitchPreference;

    @VisibleForTesting
    final boolean mDefaultValue;

    @VisibleForTesting
    final ContentObserver mContentObserver = new ContentObserver(
            new Handler(Looper.getMainLooper())) {
        @Override
        public void onChange(boolean selfChange, @Nullable Uri uri) {
            updateState(mSwitchPreference);
        }
    };

    public MagnificationOneFingerPanningPreferenceController(Context context) {
        super(context, PREF_KEY);
        boolean defaultValue;
@@ -54,10 +70,19 @@ public class MagnificationOneFingerPanningPreferenceController
        mDefaultValue = defaultValue;
    }

    @Override
    public void onResume() {
        MagnificationCapabilities.registerObserver(mContext, mContentObserver);
    }

    @Override
    public void onPause() {
        MagnificationCapabilities.unregisterObserver(mContext, mContentObserver);
    }

    @Override
    public int getAvailabilityStatus() {
        return (Flags.enableMagnificationOneFingerPanningGesture())
                ? AVAILABLE : DISABLED_FOR_USER;
        return AVAILABLE;
    }

    @Override
@@ -73,14 +98,17 @@ public class MagnificationOneFingerPanningPreferenceController
        var toReturn = Settings.Secure.putInt(mContext.getContentResolver(),
                PREF_KEY,
                (isChecked ? ON : OFF));
        if (mSwitchPreference != null) {
        refreshSummary(mSwitchPreference);
        }
        return toReturn;
    }

    @Override
    public CharSequence getSummary() {
        if (!mSwitchPreference.isEnabled()) {
            return mContext.getString(
                    R.string.accessibility_magnification_one_finger_panning_summary_unavailable);
        }

        return (isChecked())
                ? mContext.getString(
                        R.string.accessibility_magnification_one_finger_panning_summary_on)
@@ -97,6 +125,20 @@ public class MagnificationOneFingerPanningPreferenceController
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mSwitchPreference = screen.findPreference(getPreferenceKey());
        refreshSummary(mSwitchPreference);
        updateState(mSwitchPreference);
    }

    @Override
    public void updateState(Preference preference) {
        super.updateState(preference);

        if (preference == null) {
            return;
        }
        @MagnificationMode int mode =
                MagnificationCapabilities.getCapabilities(mContext);
        preference.setEnabled(
                mode == MagnificationMode.FULLSCREEN || mode == MagnificationMode.ALL);
        refreshSummary(preference);
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -202,7 +202,6 @@ public class ToggleScreenMagnificationPreferenceFragment extends
        final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY);
        generalCategory.addPreference(mSettingsPreference);

        addOneFingerPanningSetting(generalCategory);
        final MagnificationModePreferenceController magnificationModePreferenceController =
                new MagnificationModePreferenceController(getContext(),
                        MagnificationModePreferenceController.PREF_KEY);
@@ -212,6 +211,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
        addPreferenceController(magnificationModePreferenceController);

        addFollowTypingSetting(generalCategory);
        addOneFingerPanningSetting(generalCategory);
        addAlwaysOnSetting(generalCategory);
        addJoystickSetting(generalCategory);
    }
@@ -302,6 +302,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends

        var oneFingerPanningPreferenceController =
                new MagnificationOneFingerPanningPreferenceController(getContext());
        getSettingsLifecycle().addObserver(oneFingerPanningPreferenceController);
        oneFingerPanningPreferenceController.displayPreference(getPreferenceScreen());
        addPreferenceController(oneFingerPanningPreferenceController);
    }
+82 −61
Original line number Diff line number Diff line
@@ -18,19 +18,15 @@ package com.android.settings.accessibility;

import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import android.content.Context;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;

import androidx.preference.PreferenceManager;
@@ -38,131 +34,137 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;

import com.android.server.accessibility.Flags;
import com.android.settings.R;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowContentResolver;

@RunWith(RobolectricTestRunner.class)
public class MagnificationOneFingerPanningPreferenceControllerTest {
    private static final String ONE_FINGER_PANNING_KEY =
            Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;

    @Rule
    public final CheckFlagsRule mCheckFlagsRule =
            DeviceFlagsValueProvider.createCheckFlagsRule();

    private final Context mContext = ApplicationProvider.getApplicationContext();
    private ShadowContentResolver mShadowContentResolver;
    private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
    private final MagnificationOneFingerPanningPreferenceController mController =
            new MagnificationOneFingerPanningPreferenceController(mContext);

    private PreferenceScreen mScreen;

    @Before
    public void setUp() {
        mShadowContentResolver = Shadow.extract(mContext.getContentResolver());

        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
        mScreen = preferenceManager.createPreferenceScreen(mContext);
        final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
        mSwitchPreference.setKey(MagnificationOneFingerPanningPreferenceController.PREF_KEY);
        mScreen.addPreference(mSwitchPreference);
        mController.displayPreference(mScreen);
        screen.addPreference(mSwitchPreference);
        mController.displayPreference(screen);
    }

    @Test
    public void onResume_verifyRegisterCapabilityObserver() {
        mController.onResume();
        assertThat(mShadowContentResolver.getContentObservers(
                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY)))
                .hasSize(1);
    }

    @After
    public void cleanup() {
        // Can't use resetToDefaults as it NPE with
        // "Cannot invoke "android.content.IContentProvider.call"
        Settings.Secure.putInt(
                mContext.getContentResolver(),
                MagnificationOneFingerPanningPreferenceController.PREF_KEY,
                (mController.mDefaultValue) ? ON : OFF);
    @Test
    public void onPause_verifyUnregisterCapabilityObserver() {
        mController.onResume();
        mController.onPause();
        assertThat(mShadowContentResolver.getContentObservers(
                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY)))
                .isEmpty();
    }

    @Test
    public void displayPreference_defaultState_correctSummarySet() {
        assertThat(mSwitchPreference.getSummary())
                .isEqualTo(mContext.getString(
                        R.string.accessibility_magnification_one_finger_panning_summary_off));
    public void updateState_windowModeOnly_preferenceIsUnavailable() {
        MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
        mController.updateState(mSwitchPreference);

        assertThat(mSwitchPreference.isEnabled()).isFalse();
    }

    @Test
    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
    public void getAvailabilityStatus_flagDisabled_disabled() {
        int status = mController.getAvailabilityStatus();
    public void updateState_fullscreenModeOnly_preferenceIsAvailable() {
        MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.FULLSCREEN);
        mController.updateState(mSwitchPreference);

        assertThat(status).isEqualTo(DISABLED_FOR_USER);
        assertThat(mSwitchPreference.isEnabled()).isTrue();
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
    public void getAvailabilityStatus_featureFlagEnabled_enabled() {
        int status = mController.getAvailabilityStatus();
    public void updateState_switchMode_preferenceIsAvailable() {
        MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
        mController.updateState(mSwitchPreference);

        assertThat(status).isEqualTo(AVAILABLE);
        assertThat(mSwitchPreference.isEnabled()).isTrue();
    }

    @Test
    public void isChecked_defaultState_returnFalse() {
        mController.updateState(mSwitchPreference);

        assertThat(mController.isChecked()).isFalse();
        assertThat(mSwitchPreference.isChecked()).isFalse();
    }

    @Test
    public void isChecked_settingsEnabled_returnTrue() {
    public void isChecked_settingsOn_returnTrue() {
        Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
        mController.updateState(mSwitchPreference);

        assertThat(mController.isChecked()).isTrue();
    }

    @Test
    public void isChecked_settingsDisabled_returnTrue() {
    public void isChecked_settingsOff_returnFalse() {
        Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, OFF);
        mController.updateState(mSwitchPreference);

        assertThat(mController.isChecked()).isFalse();
    }

    @Test
    public void setChecked_enabled_enabledSummarySet() {
        mController.setChecked(true);

        assertThat(mSwitchPreference.getSummary()).isEqualTo(enabledSummary());
        assertThat(mController.isChecked()).isTrue();
    }
    public void getSummary_switchModeAndSettingsOff_disabledSummaryTextUsed() {
        MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
        Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, OFF);

    @Test
    public void setChecked_disabled_disabledSummarySet() {
        mController.setChecked(false);
        mController.updateState(mSwitchPreference);

        assertThat(mController.isChecked()).isFalse();
        assertThat(mSwitchPreference.getSummary()).isEqualTo(disabledSummary());
        assertThat(mController.getSummary()).isEqualTo(disabledSummary());
    }

    @Test
    public void getSummary_disable_disableSummaryTextUsed() {
        Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, OFF);
    public void getSummary_switchModeAndSettingsOn_enabledSummaryTextUsed() {
        MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
        Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);

        var summary = mController.getSummary();
        mController.updateState(mSwitchPreference);

        assertThat(summary).isEqualTo(disabledSummary());
        assertThat(mController.getSummary()).isEqualTo(enabledSummary());
    }

    @Test
    public void getSummary_enable_enabledSummaryTextUsed() {
        Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
    public void getSummary_windowModeOnly_unavailableSummaryTextUsed() {
        MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);

        var summary = mController.getSummary();
        mController.updateState(mSwitchPreference);

        assertThat(summary).isEqualTo(enabledSummary());
        assertThat(mController.getSummary()).isEqualTo(unavailableSummary());
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
    public void performClick_switchDefaultState_shouldReturnTrue() {
    public void performClick_defaultSettings_toggleOn() {
        MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
        mController.updateState(mSwitchPreference);
        reset(mSwitchPreference);

        mSwitchPreference.performClick();

        verify(mSwitchPreference).setChecked(true);
@@ -170,6 +172,20 @@ public class MagnificationOneFingerPanningPreferenceControllerTest {
        assertThat(mSwitchPreference.isChecked()).isTrue();
    }

    @Test
    public void performClick_settingsOn_toggleOff() {
        MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
        Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
        mController.updateState(mSwitchPreference);
        reset(mSwitchPreference);

        mSwitchPreference.performClick();

        verify(mSwitchPreference).setChecked(false);
        assertThat(mController.isChecked()).isFalse();
        assertThat(mSwitchPreference.isChecked()).isFalse();
    }

    private String enabledSummary() {
        return mContext.getString(
                R.string.accessibility_magnification_one_finger_panning_summary_on);
@@ -179,4 +195,9 @@ public class MagnificationOneFingerPanningPreferenceControllerTest {
        return mContext.getString(
                R.string.accessibility_magnification_one_finger_panning_summary_off);
    }

    private String unavailableSummary() {
        return mContext.getString(
                R.string.accessibility_magnification_one_finger_panning_summary_unavailable);
    }
}
+73 −1
Original line number Diff line number Diff line
@@ -122,6 +122,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {

    private static final String KEY_FOLLOW_TYPING =
            Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED;
    private static final String KEY_SINGLE_FINGER_PANNING =
            Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
    private static final String KEY_ALWAYS_ON =
            Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED;
    private static final String KEY_JOYSTICK =
@@ -215,6 +217,43 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
        assertThat(switchPreference.isChecked()).isFalse();
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
    public void onResume_defaultStateForOneFingerPan_switchPreferenceShouldReturnFalse() {
        mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();

        final TwoStatePreference switchPreference = mFragController.get().findPreference(
                MagnificationOneFingerPanningPreferenceController.PREF_KEY);
        assertThat(switchPreference).isNotNull();
        assertThat(switchPreference.isChecked()).isFalse();
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
    public void onResume_enableOneFingerPan_switchPreferenceShouldReturnTrue() {
        setKeyOneFingerPanEnabled(true);

        mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();

        final TwoStatePreference switchPreference = mFragController.get().findPreference(
                MagnificationOneFingerPanningPreferenceController.PREF_KEY);
        assertThat(switchPreference).isNotNull();
        assertThat(switchPreference.isChecked()).isTrue();
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
    public void onResume_disableOneFingerPan_switchPreferenceShouldReturnFalse() {
        setKeyOneFingerPanEnabled(false);

        mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();

        final TwoStatePreference switchPreference = mFragController.get().findPreference(
                MagnificationOneFingerPanningPreferenceController.PREF_KEY);
        assertThat(switchPreference).isNotNull();
        assertThat(switchPreference.isChecked()).isFalse();
    }

    @Test
    public void onResume_defaultStateForAlwaysOn_switchPreferenceShouldReturnTrue() {
        setAlwaysOnSupported(true);
@@ -777,6 +816,16 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
        assertThat(mFragController.get().mSettingsPreference).isNull();
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
    public void onCreateView_oneFingerPanNotSupported_settingsPreferenceIsNull() {
        mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();

        final TwoStatePreference switchPreference = mFragController.get().findPreference(
                MagnificationOneFingerPanningPreferenceController.PREF_KEY);
        assertThat(switchPreference).isNull();
    }

    @Test
    public void onCreateView_alwaysOnNotSupported_settingsPreferenceIsNull() {
        setAlwaysOnSupported(false);
@@ -817,7 +866,25 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
    }

    @Test
    public void onCreateView_addTheAlwaysOnControllerToLifeCycleObserver() {
    @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
    public void onCreateView_oneFingerPanSupported_addControllerToLifeCycleObserver() {
        Correspondence instanceOf = Correspondence.transforming(
                observer -> (observer instanceof MagnificationOneFingerPanningPreferenceController),
                "contains MagnificationOneFingerPanningPreferenceController");

        ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create(
                R.id.main_content, /* bundle= */ null).start().resume().get();

        List<LifecycleObserver> lifecycleObservers = ReflectionHelpers.getField(
                fragment.getSettingsLifecycle(), "mObservers");
        assertThat(lifecycleObservers).isNotNull();
        assertThat(lifecycleObservers).comparingElementsUsing(instanceOf).contains(true);
    }

    @Test
    public void onCreateView_alwaysOnSupported_addControllerToLifeCycleObserver() {
        setAlwaysOnSupported(true);

        Correspondence instanceOf = Correspondence.transforming(
                observer -> (observer instanceof MagnificationAlwaysOnPreferenceController),
                "contains MagnificationAlwaysOnPreferenceController");
@@ -984,6 +1051,11 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
                enabled ? ON : OFF);
    }

    private void setKeyOneFingerPanEnabled(boolean enabled) {
        Settings.Secure.putInt(mContext.getContentResolver(), KEY_SINGLE_FINGER_PANNING,
                enabled ? ON : OFF);
    }

    private void setAlwaysOnSupported(boolean supported) {
        ShadowDeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_WINDOW_MANAGER,