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

Commit 2aff3cdc authored by Isaac Chai's avatar Isaac Chai Committed by Android (Google) Code Review
Browse files

Merge "Adding feature flag and replace existing boolean with settings check" into main

parents 11d67db1 c22f2746
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());
    }
}