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

Commit c22f2746 authored by Isaac Chai's avatar Isaac Chai
Browse files

Adding feature flag and replace existing boolean with settings check

Test: Locally tested + AccessibilityUserStateTest
Bug: 282039824

Change-Id: I1706629c7505e396d8a13981488bc7b52186ef2a
parent b6e4f098
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@ flag {
    bug: "257274411"
}

flag {
    name: "enable_magnification_one_finger_panning_gesture"
    namespace: "accessibility"
    description: "Whether to allow easy-mode (one finger panning gesture) for magnification"
    bug: "282039824"
}

flag {
    name: "fix_drag_pointer_when_ending_drag"
    namespace: "accessibility"
+20 −19
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
    })
    public @interface OverscrollState {}

    @VisibleForTesting boolean mIsSinglePanningEnabled;
    @VisibleForTesting final OneFingerPanningSettingsProvider mOneFingerPanningSettingsProvider;

    private final FullScreenMagnificationVibrationHelper mFullScreenMagnificationVibrationHelper;

@@ -201,7 +201,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                displayId,
                fullScreenMagnificationVibrationHelper,
                /* magnificationLogger= */ null,
                ViewConfiguration.get(context));
                ViewConfiguration.get(context),
                new OneFingerPanningSettingsProvider(
                        context,
                        Flags.enableMagnificationOneFingerPanningGesture()
                ));
    }

    /** Constructor for tests. */
@@ -218,7 +222,9 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            int displayId,
            FullScreenMagnificationVibrationHelper fullScreenMagnificationVibrationHelper,
            MagnificationLogger magnificationLogger,
            ViewConfiguration viewConfiguration) {
            ViewConfiguration viewConfiguration,
            OneFingerPanningSettingsProvider oneFingerPanningSettingsProvider
    ) {
        super(displayId, detectSingleFingerTripleTap, detectTwoFingerTripleTap,
                detectShortcutTrigger, trace, callback);
        if (DEBUG_ALL) {
@@ -301,9 +307,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
        mPanningScalingState = new PanningScalingState(context);
        mSinglePanningState = new SinglePanningState(context);
        mFullScreenMagnificationVibrationHelper = fullScreenMagnificationVibrationHelper;
        setSinglePanningEnabled(
                context.getResources()
                        .getBoolean(R.bool.config_enable_a11y_magnification_single_panning));
        mOneFingerPanningSettingsProvider = oneFingerPanningSettingsProvider;
        mOverscrollHandler = new OverscrollHandler();
        mIsWatch = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);

@@ -317,11 +321,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
        transitionTo(mDetectingState);
    }

    @VisibleForTesting
    void setSinglePanningEnabled(boolean isEnabled) {
        mIsSinglePanningEnabled = isEnabled;
    }

    @Override
    void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (event.getActionMasked() == ACTION_DOWN) {
@@ -361,6 +360,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            Slog.i(mLogTag, "onDestroy(); delayed = "
                    + MotionEventInfo.toString(mDetectingState.mDelayedEventQueue));
        }
        mOneFingerPanningSettingsProvider.unregister();

        if (mScreenStateReceiver != null) {
            mScreenStateReceiver.unregister();
@@ -524,7 +524,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                    && event.getPointerCount() == 2 // includes the pointer currently being released
                    && mPreviousState == mViewportDraggingState) {
                // if feature flag is enabled, currently only true on watches
                if (mIsSinglePanningEnabled) {
                if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()) {
                    mOverscrollHandler.setScaleAndCenterToEdgeIfNeeded();
                    mOverscrollHandler.clearEdgeState();
                }
@@ -532,7 +532,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            } else if (action == ACTION_UP || action == ACTION_CANCEL) {
                onPanningFinished(event);
                // if feature flag is enabled, currently only true on watches
                if (mIsSinglePanningEnabled) {
                if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()) {
                    mOverscrollHandler.setScaleAndCenterToEdgeIfNeeded();
                    mOverscrollHandler.clearEdgeState();
                }
@@ -611,7 +611,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
            onPan(second);
            mFullScreenMagnificationController.offsetMagnifiedRegion(mDisplayId, distanceX,
                    distanceY, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
            if (mIsSinglePanningEnabled) {
            if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()) {
                mOverscrollHandler.onScrollStateChanged(first, second);
            }
            return /* event consumed: */ true;
@@ -1000,7 +1000,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                                && event.getPointerCount() == 2) {
                            transitionToViewportDraggingStateAndClear(event);
                        } else if (isActivated() && event.getPointerCount() == 2) {
                            if (mIsSinglePanningEnabled
                            if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()
                                    && overscrollState(event, mFirstPointerDownLocation)
                                    == OVERSCROLL_VERTICAL_EDGE) {
                                transitionToDelegatingStateAndClear();
@@ -1008,7 +1008,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                                //Primary pointer is swiping, so transit to PanningScalingState
                                transitToPanningScalingStateAndClear();
                            }
                        } else if (mIsSinglePanningEnabled
                        } else if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()
                                && isActivated()
                                && event.getPointerCount() == 1) {
                            if (overscrollState(event, mFirstPointerDownLocation)
@@ -1255,7 +1255,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                        if (isMultiTapTriggered(2 /* taps */) && event.getPointerCount() == 1) {
                            transitionToViewportDraggingStateAndClear(event);
                        } else if (isActivated() && event.getPointerCount() == 2) {
                            if (mIsSinglePanningEnabled
                            if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()
                                    && overscrollState(event, mFirstPointerDownLocation)
                                    == OVERSCROLL_VERTICAL_EDGE) {
                                transitionToDelegatingStateAndClear();
@@ -1263,7 +1263,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                                //Primary pointer is swiping, so transit to PanningScalingState
                                transitToPanningScalingStateAndClear();
                            }
                        } else if (mIsSinglePanningEnabled
                        } else if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()
                                && isActivated()
                                && event.getPointerCount() == 1) {
                            if (overscrollState(event, mFirstPointerDownLocation)
@@ -1633,7 +1633,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
                + ", mPreviousState=" + State.nameOf(mPreviousState)
                + ", mMagnificationController=" + mFullScreenMagnificationController
                + ", mDisplayId=" + mDisplayId
                + ", mIsSinglePanningEnabled=" + mIsSinglePanningEnabled
                + ", mIsSinglePanningEnabled="
                + mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()
                + ", mOverscrollHandler=" + mOverscrollHandler
                + '}';
    }
+104 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.server.accessibility.magnification;


import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.provider.Settings;

import androidx.annotation.VisibleForTesting;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Provider for secure settings {@link Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED}.
 */
public class OneFingerPanningSettingsProvider {

    @VisibleForTesting
    static final String KEY = Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
    private static final Uri URI = Settings.Secure.getUriFor(KEY);
    private AtomicBoolean mCached = new AtomicBoolean();
    @VisibleForTesting
    ContentObserver mObserver;
    @VisibleForTesting
    ContentResolver mContentResolver;

    @Retention(RetentionPolicy.SOURCE)
    public @interface State {
        int OFF = 0;
        int ON = 1;
    }

    public OneFingerPanningSettingsProvider(
            Context context,
            boolean featureFlagEnabled
    ) {
        var defaultValue = isOneFingerPanningEnabledDefault(context);
        if (featureFlagEnabled) {
            mContentResolver = context.getContentResolver();
            mObserver = new ContentObserver(context.getMainThreadHandler()) {
                @Override
                public void onChange(boolean selfChange) {
                    mCached.set(isOneFingerPanningEnabledInSetting(context, defaultValue));
                }
            };
            mCached.set(isOneFingerPanningEnabledInSetting(context, defaultValue));
            mContentResolver.registerContentObserver(URI, false, mObserver);
        } else {
            mCached.set(defaultValue);
        }
    }

    /** Returns whether one finger panning is enabled.. */
    public boolean isOneFingerPanningEnabled() {
        return mCached.get();
    }

    /** Unregister content observer for listening to secure settings. */
    public void unregister() {
        if (mContentResolver != null) {
            mContentResolver.unregisterContentObserver(mObserver);
        }
        mContentResolver = null;
    }

    private boolean isOneFingerPanningEnabledInSetting(Context context, boolean defaultValue) {
        return State.ON == Settings.Secure.getIntForUser(
                mContentResolver,
                KEY,
                (defaultValue ? State.ON : State.OFF),
                context.getUserId());
    }

    @VisibleForTesting
    static boolean isOneFingerPanningEnabledDefault(Context context) {
        boolean oneFingerPanningDefaultValue;
        try {
            oneFingerPanningDefaultValue = context.getResources().getBoolean(
                    com.android.internal.R.bool.config_enable_a11y_magnification_single_panning);
        } catch (Resources.NotFoundException e) {
            oneFingerPanningDefaultValue = false;
        }
        return oneFingerPanningDefaultValue;
    }
}
+25 −18
Original line number Diff line number Diff line
@@ -189,6 +189,8 @@ public class FullScreenMagnificationGestureHandlerTest {
    FullScreenMagnificationVibrationHelper mMockFullScreenMagnificationVibrationHelper;
    @Mock
    FullScreenMagnificationGestureHandler.MagnificationLogger mMockMagnificationLogger;
    @Mock
    OneFingerPanningSettingsProvider mMockOneFingerPanningSettingsProvider;

    @Rule
    public final TestableContext mContext = new TestableContext(getInstrumentation().getContext());
@@ -266,6 +268,7 @@ public class FullScreenMagnificationGestureHandlerTest {
        mMgh.onDestroy();
        mFullScreenMagnificationController.unregister(DISPLAY_0);
        verify(mWindowMagnificationPromptController).onDestroy();
        verify(mMockOneFingerPanningSettingsProvider).unregister();
        Settings.Secure.putFloatForUser(mContext.getContentResolver(),
                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
                mOriginalMagnificationPersistedScale,
@@ -288,11 +291,10 @@ public class FullScreenMagnificationGestureHandlerTest {
                        DISPLAY_0,
                        mMockFullScreenMagnificationVibrationHelper,
                        mMockMagnificationLogger,
                        ViewConfiguration.get(mContext));
                        ViewConfiguration.get(mContext),
                        mMockOneFingerPanningSettingsProvider);
        if (isWatch()) {
            h.setSinglePanningEnabled(true);
        } else {
            h.setSinglePanningEnabled(false);
            enableOneFingerPanning(true);
        }
        mHandler = new TestHandler(h.mDetectingState, mClock) {
            @Override
@@ -607,8 +609,8 @@ public class FullScreenMagnificationGestureHandlerTest {
    @Test
    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
    public void testTwoFingerTap_StateIsActivated_shouldInDelegating() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        mMgh.setSinglePanningEnabled(false);
        assumeTrue(isWatch());
        enableOneFingerPanning(false);
        goFromStateIdleTo(STATE_ACTIVATED);
        allowEventDelegation();

@@ -623,8 +625,8 @@ public class FullScreenMagnificationGestureHandlerTest {
    @Test
    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
    public void testTwoFingerTap_StateIsIdle_shouldInDelegating() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        mMgh.setSinglePanningEnabled(false);
        assumeTrue(isWatch());
        enableOneFingerPanning(false);
        goFromStateIdleTo(STATE_IDLE);
        allowEventDelegation();

@@ -830,7 +832,7 @@ public class FullScreenMagnificationGestureHandlerTest {

    @Test
    public void testActionUpNotAtEdge_singlePanningState_detectingState() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        assumeTrue(isWatch());
        goFromStateIdleTo(STATE_SINGLE_PANNING);

        send(upEvent());
@@ -841,8 +843,8 @@ public class FullScreenMagnificationGestureHandlerTest {

    @Test
    public void testScroll_SinglePanningDisabled_delegatingState() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        mMgh.setSinglePanningEnabled(false);
        assumeTrue(isWatch());
        enableOneFingerPanning(false);

        goFromStateIdleTo(STATE_ACTIVATED);
        allowEventDelegation();
@@ -854,7 +856,7 @@ public class FullScreenMagnificationGestureHandlerTest {
    @Test
    @FlakyTest
    public void testScroll_singleHorizontalPanningAndAtEdge_leftEdgeOverscroll() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        assumeTrue(isWatch());
        goFromStateIdleTo(STATE_SINGLE_PANNING);
        float centerY =
                (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.bottom) / 2.0f;
@@ -878,7 +880,7 @@ public class FullScreenMagnificationGestureHandlerTest {
    @Test
    @FlakyTest
    public void testScroll_singleHorizontalPanningAndAtEdge_rightEdgeOverscroll() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        assumeTrue(isWatch());
        goFromStateIdleTo(STATE_SINGLE_PANNING);
        float centerY =
                (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.bottom) / 2.0f;
@@ -902,7 +904,7 @@ public class FullScreenMagnificationGestureHandlerTest {
    @Test
    @FlakyTest
    public void testScroll_singleVerticalPanningAndAtEdge_verticalOverscroll() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        assumeTrue(isWatch());
        goFromStateIdleTo(STATE_SINGLE_PANNING);
        float centerX =
                (INITIAL_MAGNIFICATION_BOUNDS.right + INITIAL_MAGNIFICATION_BOUNDS.left) / 2.0f;
@@ -924,7 +926,7 @@ public class FullScreenMagnificationGestureHandlerTest {

    @Test
    public void testScroll_singlePanningAndAtEdge_noOverscroll() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        assumeTrue(isWatch());
        goFromStateIdleTo(STATE_SINGLE_PANNING);
        float centerY =
                (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.bottom) / 2.0f;
@@ -946,7 +948,7 @@ public class FullScreenMagnificationGestureHandlerTest {

    @Test
    public void testScroll_singleHorizontalPanningAndAtEdge_vibrate() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        assumeTrue(isWatch());
        goFromStateIdleTo(STATE_SINGLE_PANNING);
        mFullScreenMagnificationController.setCenter(
                DISPLAY_0,
@@ -970,7 +972,7 @@ public class FullScreenMagnificationGestureHandlerTest {

    @Test
    public void testScroll_singleVerticalPanningAndAtEdge_doNotVibrate() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        assumeTrue(isWatch());
        goFromStateIdleTo(STATE_SINGLE_PANNING);
        mFullScreenMagnificationController.setCenter(
                DISPLAY_0,
@@ -993,8 +995,9 @@ public class FullScreenMagnificationGestureHandlerTest {
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_FULLSCREEN_FLING_GESTURE)
    public void singleFinger_testScrollAfterMagnified_startsFling() {
        assumeTrue(mMgh.mIsSinglePanningEnabled);
        assumeTrue(isWatch());
        goFromStateIdleTo(STATE_ACTIVATED);

        swipeAndHold();
@@ -1274,6 +1277,10 @@ public class FullScreenMagnificationGestureHandlerTest {
        mFullScreenMagnificationController.reset(DISPLAY_0, /* animate= */ false);
    }

    private void enableOneFingerPanning(boolean enable) {
        when(mMockOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()).thenReturn(enable);
    }

    private void assertActionsInOrder(List<MotionEvent> actualEvents,
            List<Integer> expectedActions) {
        assertTrue(actualEvents.size() == expectedActions.size());
+153 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.server.accessibility.magnification;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

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

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

import android.provider.Settings;
import android.testing.TestableContext;

import androidx.test.runner.AndroidJUnit4;

import com.android.server.accessibility.magnification.OneFingerPanningSettingsProvider.State;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public class OneFingerPanningSettingsProviderTest {

    @Rule
    public final TestableContext mContext = new TestableContext(getInstrumentation().getContext());

    private boolean mDefaultValue;
    private boolean mOriginalIsOneFingerPanningEnabled;

    private OneFingerPanningSettingsProvider mProvider;

    @Before
    public void setup() {
        mDefaultValue = OneFingerPanningSettingsProvider.isOneFingerPanningEnabledDefault(mContext);
        mOriginalIsOneFingerPanningEnabled = isSecureSettingsEnabled();
    }

    @After
    public void tearDown() {
        enableSecureSettings(mOriginalIsOneFingerPanningEnabled);
        if (mProvider != null) {
            mProvider.unregister();
        }
    }

    @Test
    public void isOneFingerPanningEnabled_flagDisabled_matchesDefault() {
        mProvider = new OneFingerPanningSettingsProvider(mContext, /* featureFlagEnabled */ false);

        assertThat(mProvider.isOneFingerPanningEnabled()).isEqualTo(mDefaultValue);
    }

    @Test
    public void isOneFingerPanningEnabled_flagEnabledSettingEnabled_true() {
        enableSecureSettings(true);
        mProvider = new OneFingerPanningSettingsProvider(mContext, /* featureFlagEnabled */ true);

        assertTrue(mProvider.isOneFingerPanningEnabled());
    }

    @Test
    public void isOneFingerPanningEnabled_flagEnabledSettingDisabled_false() {
        enableSecureSettings(false);
        mProvider = new OneFingerPanningSettingsProvider(mContext, /* featureFlagEnabled */ true);

        assertFalse(mProvider.isOneFingerPanningEnabled());
    }

    @Test
    public void isOneFingerPanningEnabled_flagEnabledSettingsFalse_false() {
        mProvider = new OneFingerPanningSettingsProvider(mContext, /* featureFlagEnabled */ true);

        // Simulate observer triggered.
        enableSecureSettings(false);
        mProvider.mObserver.onChange(/* selfChange= */ false);

        assertFalse(mProvider.isOneFingerPanningEnabled());
    }

    @Test
    public void isOneFingerPanningEnabled_flagEnabledSettingsTrue_true() {
        mProvider = new OneFingerPanningSettingsProvider(mContext, /* featureFlagEnabled */ true);

        // Simulate observer triggered.
        enableSecureSettings(true);
        mProvider.mObserver.onChange(/* selfChange= */ false);

        assertTrue(mProvider.isOneFingerPanningEnabled());
    }

    @Test
    public void isOneFingerPanningEnabled_flagDisabledSettingsChanges_valueUnchanged() {
        mProvider = new OneFingerPanningSettingsProvider(mContext, /* featureFlagEnabled */ false);
        var previousValue = mProvider.isOneFingerPanningEnabled();

        enableSecureSettings(!previousValue);

        assertThat(mProvider.isOneFingerPanningEnabled()).isEqualTo(previousValue);
        assertThat(mProvider.isOneFingerPanningEnabled()).isEqualTo(mDefaultValue);
    }

    @Test
    public void unregister_featureEnabled_contentResolverNull() {
        var provider = new OneFingerPanningSettingsProvider(
                mContext, /* featureFlagEnabled */ true);

        provider.unregister();

        assertThat(provider.mContentResolver).isNull();
    }

    @Test
    public void unregister_featureDisabled_noError() {
        var provider = new OneFingerPanningSettingsProvider(
                mContext, /* featureFlagEnabled */ false);

        provider.unregister();
    }

    private void enableSecureSettings(boolean enable) {
        Settings.Secure.putIntForUser(
                mContext.getContentResolver(),
                OneFingerPanningSettingsProvider.KEY,
                enable ? State.ON : State.OFF,
                mContext.getUserId());
    }

    private boolean isSecureSettingsEnabled() {
        return State.ON == Settings.Secure.getIntForUser(
                mContext.getContentResolver(),
                OneFingerPanningSettingsProvider.KEY,
                mDefaultValue ? State.ON : State.OFF,
                mContext.getUserId());
    }
}