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

Commit e50d119d authored by Jeffrey Huang's avatar Jeffrey Huang Committed by Android (Google) Code Review
Browse files

Merge "Introduce StayAwakePreferenceController"

parents a15ec6d8 f4e1295f
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -32,8 +32,10 @@ import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.development.DevelopmentSettingsEnabler;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@@ -116,7 +118,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra

    @Override
    protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
        return buildPreferenceControllers(context);
        return buildPreferenceControllers(context, getLifecycle());
    }

    void onEnableDevelopmentOptionsConfirmed() {
@@ -129,8 +131,12 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
        mSwitchBar.setChecked(false);
    }

    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
        return null;
    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
            Lifecycle lifecycle) {
        final List<AbstractPreferenceController> controllers = new ArrayList<>();
        controllers.add(new StayAwakePreferenceController(context, lifecycle));

        return controllers;
    }

    /**
@@ -156,7 +162,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
                @Override
                public List<AbstractPreferenceController> getPreferenceControllers(Context
                        context) {
                    return buildPreferenceControllers(context);
                    return buildPreferenceControllers(context, null /* lifecycle */);
                }
            };
}
+139 −0
Original line number Diff line number Diff line
package com.android.settings.development;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Handler;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;

import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
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 StayAwakePreferenceController extends AbstractPreferenceController implements
        PreferenceControllerMixin, Preference.OnPreferenceChangeListener, LifecycleObserver,
        OnResume, OnPause {

    private static final String TAG = "StayAwakeCtrl";
    private static final String PREFERENCE_KEY = "keep_screen_on";
    @VisibleForTesting
    static final int SETTING_VALUE_OFF = 0;
    @VisibleForTesting
    static final int SETTING_VALUE_ON =
            BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB
                    | BatteryManager.BATTERY_PLUGGED_WIRELESS;
    @VisibleForTesting
    SettingsObserver mSettingsObserver;

    private RestrictedSwitchPreference mPreference;

    public StayAwakePreferenceController(Context context, Lifecycle lifecycle) {
        super(context);
        mSettingsObserver = new SettingsObserver();

        if (lifecycle != null) {
            lifecycle.addObserver(this);
        }
    }

    @Override
    public boolean isAvailable() {
        return true;
    }

    @Override
    public String getPreferenceKey() {
        return PREFERENCE_KEY;
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = (RestrictedSwitchPreference) screen.findPreference(getPreferenceKey());
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        final boolean stayAwake = (Boolean) newValue;
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                stayAwake ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
        return true;
    }

    @Override
    public void updateState(Preference preference) {
        final RestrictedLockUtils.EnforcedAdmin admin = checkIfMaximumTimeToLockSetByAdmin();
        if (admin != null) {
            mPreference.setDisabledByAdmin(admin);
            return;
        }

        final int stayAwakeMode = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                SETTING_VALUE_OFF);
        mPreference.setChecked(stayAwakeMode != SETTING_VALUE_OFF);
    }

    @Override
    public void onResume() {
        if (mPreference != null) {
            mSettingsObserver.register(true /* register */);
        }
    }

    @Override
    public void onPause() {
        if (mPreference != null) {
            mSettingsObserver.register(false /* unregister */);
        }
    }

    @VisibleForTesting
    RestrictedLockUtils.EnforcedAdmin checkIfMaximumTimeToLockSetByAdmin() {
        // A DeviceAdmin has specified a maximum time until the device
        // will lock...  in this case we can't allow the user to turn
        // on "stay awake when plugged in" because that would defeat the
        // restriction.
        return RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
    }

    @VisibleForTesting
    class SettingsObserver extends ContentObserver {
        private final Uri mStayAwakeUri = Settings.Global.getUriFor(
                Settings.Global.STAY_ON_WHILE_PLUGGED_IN);

        public SettingsObserver() {
            super(new Handler());
        }

        public void register(boolean register) {
            final ContentResolver cr = mContext.getContentResolver();
            if (register) {
                cr.registerContentObserver(
                        mStayAwakeUri, false, this);
            } else {
                cr.unregisterContentObserver(this);
            }
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
            if (mStayAwakeUri.equals(uri)) {
                updateState(mPreference);
            }
        }
    }
}
+117 −0
Original line number Diff line number Diff line
package com.android.settings.development;

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

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.support.v7.preference.PreferenceScreen;

import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class StayAwakePreferenceControllerTest {

    @Mock
    private Context mContext;
    @Mock
    private RestrictedSwitchPreference mPreference;
    @Mock
    private PreferenceScreen mPreferenceScreen;
    @Mock
    private Lifecycle mLifecycle;
    private ContentResolver mContentResolver;
    private StayAwakePreferenceController mController;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mContentResolver = RuntimeEnvironment.application.getContentResolver();
        mController = new StayAwakePreferenceController(mContext, mLifecycle);
        when(mContext.getContentResolver()).thenReturn(mContentResolver);
        when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
                mPreference);
        mController.displayPreference(mPreferenceScreen);
    }

    @Test
    public void onPreferenceChanged_turnOnStayAwake() {
        mController.onPreferenceChange(null, true);

        final int mode = Settings.System.getInt(mContentResolver,
                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, -1);
        assertThat(mode).isEqualTo(StayAwakePreferenceController.SETTING_VALUE_ON);
    }

    @Test
    public void onPreferenceChanged_turnOffStayAwake() {
        mController.onPreferenceChange(null, false);

        final int mode = Settings.System.getInt(mContentResolver,
                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, -1);
        assertThat(mode).isEqualTo(StayAwakePreferenceController.SETTING_VALUE_OFF);
    }

    @Test
    public void updateState_preferenceShouldBeChecked() {
        Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                StayAwakePreferenceController.SETTING_VALUE_ON);
        mController.updateState(mPreference);
        verify(mPreference).setChecked(true);
    }

    @Test
    public void updateState_preferenceShouldNotBeChecked() {
        Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                StayAwakePreferenceController.SETTING_VALUE_OFF);
        mController.updateState(mPreference);
        verify(mPreference).setChecked(false);
    }

    @Test
    public void displayPreference_expectSetDisabledByAdminToBeCalled() {
        mController = spy(mController);
        RestrictedLockUtils.EnforcedAdmin admin = Mockito.mock(
                RestrictedLockUtils.EnforcedAdmin.class);
        doReturn(admin).when(mController).checkIfMaximumTimeToLockSetByAdmin();
        mController.updateState(mPreference);
        verify(mPreference).setDisabledByAdmin(admin);
    }

    @Test
    public void observerOnChangeCalledWithSameUri_preferenceShouldBeUpdated() {
        Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                StayAwakePreferenceController.SETTING_VALUE_ON);
        mController.mSettingsObserver.onChange(false,
                Settings.Global.getUriFor(Settings.Global.STAY_ON_WHILE_PLUGGED_IN));
        verify(mPreference).setChecked(true);
    }

    @Test
    public void observerOnChangeCalledWithDifferentUri_preferenceShouldNotBeUpdated() {
        Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                StayAwakePreferenceController.SETTING_VALUE_ON);
        mController.mSettingsObserver.onChange(false, null);
        verify(mPreference, never()).setChecked(true);
    }
}