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

Commit 4b958796 authored by Doris Ling's avatar Doris Ling Committed by Fan Zhang
Browse files

Listen to brigtness updates to update brightness summary.

- add content observer for brightness relates changes, and update the
brightness preference summary when changes occur.
- also check for VR mode and auto brightness mode when reading the
current brightness value.

Merged-In: I895d251e1dc12cb114ef00328eb8aa0075d77ab1
Change-Id: Ice549ffd708c2dad311a87b6a92bf1c8db426456
Fix: 37227609
Test: make RunSettingsRoboTests
parent a0e617f9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ public class DisplaySettings extends DashboardFragment {
        controllers.add(new VrDisplayPreferenceController(context));
        controllers.add(new WallpaperPreferenceController(context));
        controllers.add(new ThemePreferenceController(context));
        controllers.add(new BrightnessLevelPreferenceController(context));
        controllers.add(new BrightnessLevelPreferenceController(context, lifecycle));
        return controllers;
    }

+122 −7
Original line number Diff line number Diff line
@@ -13,20 +13,79 @@
 */
package com.android.settings.display;

import static android.provider.Settings.System.SCREEN_BRIGHTNESS;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.provider.Settings.System;
import android.service.vr.IVrManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.util.Log;

import com.android.settings.core.PreferenceController;
import com.android.settings.core.lifecycle.Lifecycle;
import com.android.settings.core.lifecycle.LifecycleObserver;
import com.android.settings.core.lifecycle.events.OnPause;
import com.android.settings.core.lifecycle.events.OnResume;

import java.text.NumberFormat;

public class BrightnessLevelPreferenceController extends PreferenceController {
public class BrightnessLevelPreferenceController extends PreferenceController implements
        LifecycleObserver, OnResume, OnPause {

    private static final String TAG = "BrightnessPrefCtrl";
    private static final String KEY_BRIGHTNESS = "brightness";
    private static final Uri BRIGHTNESS_MODE_URI;
    private static final Uri BRIGHTNESS_URI;
    private static final Uri BRIGHTNESS_FOR_VR_URI;
    private static final Uri BRIGHTNESS_ADJ_URI;

    private final int mMinBrightness;
    private final int mMaxBrightness;
    private final int mMinVrBrightness;
    private final int mMaxVrBrightness;
    private final ContentResolver mContentResolver;

    private Preference mPreference;

    public BrightnessLevelPreferenceController(Context context) {
    static {
        BRIGHTNESS_MODE_URI = System.getUriFor(System.SCREEN_BRIGHTNESS_MODE);
        BRIGHTNESS_URI = System.getUriFor(System.SCREEN_BRIGHTNESS);
        BRIGHTNESS_FOR_VR_URI = System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR);
        BRIGHTNESS_ADJ_URI = System.getUriFor(System.SCREEN_AUTO_BRIGHTNESS_ADJ);
    }

    private ContentObserver mBrightnessObserver = new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange) {
            updatedSummary(mPreference);
        }
    };

    public BrightnessLevelPreferenceController(Context context, Lifecycle lifecycle) {
        this(context, lifecycle, new PowerManagerWrapper(
                (PowerManager) context.getSystemService(Context.POWER_SERVICE)));
    }

    @VisibleForTesting
    public BrightnessLevelPreferenceController(Context context, Lifecycle lifecycle,
            PowerManagerWrapper powerManagerWrapper) {
        super(context);
        if (lifecycle != null) {
            lifecycle.addObserver(this);
        }
        mMinBrightness = powerManagerWrapper.getMinimumScreenBrightnessSetting();
        mMaxBrightness = powerManagerWrapper.getMaximumScreenBrightnessSetting();
        mMinVrBrightness = powerManagerWrapper.getMinimumScreenBrightnessForVrSetting();
        mMaxVrBrightness = powerManagerWrapper.getMaximumScreenBrightnessForVrSetting();
        mContentResolver = mContext.getContentResolver();
    }

    @Override
@@ -39,11 +98,67 @@ public class BrightnessLevelPreferenceController extends PreferenceController {
        return KEY_BRIGHTNESS;
    }

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

    @Override
    public void updateState(Preference preference) {
        final double brightness = Settings.System.getInt(mContext.getContentResolver(),
            SCREEN_BRIGHTNESS, 0);
        preference.setSummary(NumberFormat.getPercentInstance().format(brightness / 255));
        updatedSummary(preference);
    }

    @Override
    public void onResume() {
        mContentResolver.registerContentObserver(BRIGHTNESS_MODE_URI, false, mBrightnessObserver);
        mContentResolver.registerContentObserver(BRIGHTNESS_URI, false, mBrightnessObserver);
        mContentResolver.registerContentObserver(BRIGHTNESS_FOR_VR_URI, false, mBrightnessObserver);
        mContentResolver.registerContentObserver(BRIGHTNESS_ADJ_URI, false, mBrightnessObserver);
    }

    @Override
    public void onPause() {
        mContentResolver.unregisterContentObserver(mBrightnessObserver);
    }

    private void updatedSummary(Preference preference) {
        if (preference != null) {
            preference.setSummary(NumberFormat.getPercentInstance().format(getCurrentBrightness()));
        }
    }

    private double getCurrentBrightness() {
        if (isInVrMode()) {
            final double value = System.getInt(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR,
                    mMaxBrightness);
            return getPercentage(value, mMinVrBrightness, mMaxVrBrightness);
        }
        final int brightnessMode = Settings.System.getInt(mContentResolver,
                System.SCREEN_BRIGHTNESS_MODE, System.SCREEN_BRIGHTNESS_MODE_MANUAL);
        if (brightnessMode == System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
            final float value = Settings.System.getFloat(mContentResolver,
                    System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
            // auto brightness is between -1 and 1
            return ((value + 1)) / 2;
        }
        final double value = Settings.System.getInt(mContentResolver, System.SCREEN_BRIGHTNESS,
                mMinBrightness);
        return getPercentage(value, mMinBrightness, mMaxBrightness);
    }

    private double getPercentage(double value, int min, int max) {
        return (value - min) / (max - min);
    }

    @VisibleForTesting
    boolean isInVrMode() {
        try {
            return IVrManager.Stub.asInterface(ServiceManager.getService(Context.VR_SERVICE))
                    .getVrModeState();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to check vr mode!", e);
        }
        return false;
    }
}
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.display;

import android.os.PowerManager;

/**
 * This class replicates a subset of the android.os.PowerManager. The class exists so that we can
 * use a thin wrapper around the PowerManager in production code and a mock in tests. We cannot
 * directly mock or shadow the PowerManager, because some of the methods we rely on are newer than
 * the API version supported by Robolectric or are hidden.
 */
public class PowerManagerWrapper {
    private final PowerManager mPowerManager;

    public PowerManagerWrapper(PowerManager powerManager) {
        mPowerManager = powerManager;
    }

    public int getMinimumScreenBrightnessSetting() {
        return mPowerManager.getMinimumScreenBrightnessSetting();
    }

    public int getMaximumScreenBrightnessSetting() {
        return mPowerManager.getMaximumScreenBrightnessSetting();
    }

    public int getMinimumScreenBrightnessForVrSetting() {
        return mPowerManager.getMinimumScreenBrightnessForVrSetting();
    }

    public int getMaximumScreenBrightnessForVrSetting() {
        return mPowerManager.getMaximumScreenBrightnessForVrSetting();
    }
}
+91 −10
Original line number Diff line number Diff line
@@ -16,27 +16,31 @@

package com.android.settings.display;

import static android.provider.Settings.System.SCREEN_BRIGHTNESS;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
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.provider.Settings.System;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;

import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;

import java.text.NumberFormat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.internal.ShadowExtractor;
import org.robolectric.shadows.ShadowContentResolver;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -46,6 +50,10 @@ public class BrightnessLevelPreferenceControllerTest {
    @Mock
    private ContentResolver mContentResolver;
    @Mock
    private PowerManagerWrapper mPowerManager;
    @Mock
    private PreferenceScreen mScreen;
    @Mock
    private Preference mPreference;

    private BrightnessLevelPreferenceController mController;
@@ -53,8 +61,15 @@ public class BrightnessLevelPreferenceControllerTest {
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        when(mContext.getContentResolver()).thenReturn(mContentResolver);
        when(mPowerManager.getMinimumScreenBrightnessSetting()).thenReturn(0);
        when(mPowerManager.getMaximumScreenBrightnessSetting()).thenReturn(100);
        when(mPowerManager.getMinimumScreenBrightnessForVrSetting()).thenReturn(0);
        when(mPowerManager.getMaximumScreenBrightnessForVrSetting()).thenReturn(100);
        when(mScreen.findPreference(anyString())).thenReturn(mPreference);
        mController = spy(new BrightnessLevelPreferenceController(mContext, null, mPowerManager));
        doReturn(false).when(mController).isInVrMode();

        mController = new BrightnessLevelPreferenceController(mContext);
    }

    @Test
@@ -63,14 +78,80 @@ public class BrightnessLevelPreferenceControllerTest {
    }

    @Test
    public void updateState_shouldSetSummary() {
        final NumberFormat formatter = NumberFormat.getPercentInstance();
        when(mContext.getContentResolver()).thenReturn(mContentResolver);
        Settings.System.putInt(mContentResolver, SCREEN_BRIGHTNESS, 45);
    public void onResume_shouldRegisterObserver() {
        Context context = RuntimeEnvironment.application;
        BrightnessLevelPreferenceController controller =
            new BrightnessLevelPreferenceController(context, null, mPowerManager);
        ShadowContentResolver shadowContentResolver =
            (ShadowContentResolver) ShadowExtractor.extract(context.getContentResolver());

        controller.onResume();

        assertThat(shadowContentResolver.getContentObservers(
            System.getUriFor(System.SCREEN_BRIGHTNESS_MODE))).isNotEmpty();
        assertThat(shadowContentResolver.getContentObservers(
            System.getUriFor(System.SCREEN_BRIGHTNESS))).isNotEmpty();
        assertThat(shadowContentResolver.getContentObservers(
            System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR))).isNotEmpty();
        assertThat(shadowContentResolver.getContentObservers(
            System.getUriFor(System.SCREEN_AUTO_BRIGHTNESS_ADJ))).isNotEmpty();
    }

    @Test
    public void onPause_shouldUnregisterObserver() {
        Context context = RuntimeEnvironment.application;
        BrightnessLevelPreferenceController controller =
            new BrightnessLevelPreferenceController(context, null, mPowerManager);
        ShadowContentResolver shadowContentResolver =
            (ShadowContentResolver) ShadowExtractor.extract(context.getContentResolver());

        controller.displayPreference(mScreen);
        controller.onResume();
        controller.onPause();

        assertThat(shadowContentResolver.getContentObservers(
            System.getUriFor(System.SCREEN_BRIGHTNESS_MODE))).isEmpty();
        assertThat(shadowContentResolver.getContentObservers(
            System.getUriFor(System.SCREEN_BRIGHTNESS))).isEmpty();
        assertThat(shadowContentResolver.getContentObservers(
            System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR))).isEmpty();
        assertThat(shadowContentResolver.getContentObservers(
            System.getUriFor(System.SCREEN_AUTO_BRIGHTNESS_ADJ))).isEmpty();
    }

    @Test
    public void updateState_inVrMode_shouldSetSummaryToVrBrightness() {
        doReturn(true).when(mController).isInVrMode();
        System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR, 85);

        mController.updateState(mPreference);

        verify(mPreference).setSummary(formatter.format(45.0 / 255));
        verify(mPreference).setSummary("85%");
    }

    @Test
    public void updateState_autoBrightness_shouldSetSummaryToVrBrightness() {
        doReturn(false).when(mController).isInVrMode();
        System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_MODE,
            System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);

        System.putFloat(mContentResolver, System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f);

        mController.updateState(mPreference);

        verify(mPreference).setSummary("50%");
    }

    @Test
    public void updateState_manualBrightness_shouldSetSummaryToVrBrightness() {
        doReturn(false).when(mController).isInVrMode();
        System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_MODE,
            System.SCREEN_BRIGHTNESS_MODE_MANUAL);

        System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, 45);

        mController.updateState(mPreference);

        verify(mPreference).setSummary("45%");
    }
}
+13 −18
Original line number Diff line number Diff line
@@ -17,35 +17,30 @@

package com.android.settings.search;

import android.content.Context;
import static com.google.common.truth.Truth.assertThat;

import android.content.Context;
import android.util.ArrayMap;

import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.core.PreferenceController;
import com.android.settings.display.AutoBrightnessPreferenceController;
import com.android.settings.gestures.DoubleTapPowerPreferenceController;
import com.android.settings.gestures.DoubleTapScreenPreferenceController;
import com.android.settings.gestures.DoubleTwistPreferenceController;
import com.android.settings.gestures.PickupGesturePreferenceController;
import com.android.settings.gestures.SwipeToNotificationPreferenceController;
import com.android.settings.deviceinfo.SystemUpdatePreferenceController;
import com.android.settings.search2.DatabaseIndexingUtils;

import com.android.settings.search2.IntentPayload;
import com.android.settings.search2.ResultPayload;

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

import java.util.Map;

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

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class DatabaseIndexingUtilsTest {
@@ -57,7 +52,7 @@ public class DatabaseIndexingUtilsTest {
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = ShadowApplication.getInstance().getApplicationContext();
        mContext = RuntimeEnvironment.application;
    }

    @Test
@@ -74,11 +69,11 @@ public class DatabaseIndexingUtilsTest {

    @Test
    public void testGetPreferenceControllerUriMap_CompatibleClass_ReturnsValidMap() {
        String className = "com.android.settings.DisplaySettings";

        Map map = DatabaseIndexingUtils.getPreferenceControllerUriMap(className, mContext);
        assertThat(map.get("auto_brightness"))
                .isInstanceOf(AutoBrightnessPreferenceController.class);
        final String className = "com.android.settings.system.SystemDashboardFragment";
        final Map<String, PreferenceController> map =
                DatabaseIndexingUtils.getPreferenceControllerUriMap(className, mContext);
        assertThat(map.get("system_update_settings"))
                .isInstanceOf(SystemUpdatePreferenceController.class);
    }

    @Test