OSDN Git Service

Listen to brigtness updates to update brightness summary.
authorDoris Ling <dling@google.com>
Thu, 13 Apr 2017 22:06:36 +0000 (15:06 -0700)
committerFan Zhang <zhfan@google.com>
Tue, 18 Apr 2017 20:01:16 +0000 (20:01 +0000)
- 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

src/com/android/settings/DisplaySettings.java
src/com/android/settings/display/BrightnessLevelPreferenceController.java
src/com/android/settings/display/PowerManagerWrapper.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java
tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java

index 1230ae5..b29f8a0 100644 (file)
@@ -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;
     }
 
index e0000d6..d012ac3 100644 (file)
  */
 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;
+
+    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);
+    }
 
-    public BrightnessLevelPreferenceController(Context context) {
+    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
@@ -40,10 +99,66 @@ public class BrightnessLevelPreferenceController extends PreferenceController {
     }
 
     @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;
+    }
 }
diff --git a/src/com/android/settings/display/PowerManagerWrapper.java b/src/com/android/settings/display/PowerManagerWrapper.java
new file mode 100644 (file)
index 0000000..afa2f33
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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();
+    }
+}
index 025e1ae..0b33089 100644 (file)
 
 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%");
+    }
 }
index f4370fc..fa0170c 100644 (file)
 
 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
@@ -106,7 +101,7 @@ public class DatabaseIndexingUtilsTest {
                 return new IntentPayload(null);
             }
         };
-        ArrayMap<String,PreferenceController> map = new ArrayMap<>();
+        ArrayMap<String, PreferenceController> map = new ArrayMap<>();
         map.put(key, prefController);
 
         ResultPayload payload = DatabaseIndexingUtils.getPayloadFromUriMap(map, key);