blob: a031b9ae521511e3139ea39e61cbd951b7cadd71 [file] [log] [blame]
/*
* Copyright (C) 2022 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.clockwork.displayoffload;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.clockwork.ArrayUtils;
import com.android.clockwork.power.AmbientConfig;
import com.android.internal.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.LooperMode;
import org.robolectric.shadows.ShadowSensor;
import org.robolectric.shadows.ShadowSensorManager;
import java.util.ArrayList;
/**
* Tests for {@link com.google.android.clockwork.displayoffload.BrightnessOffloadController}.
*/
@RunWith(AndroidJUnit4.class)
@LooperMode(LooperMode.Mode.LEGACY)
public class BrightnessOffloadControllerTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private final ShadowSensorManager mShadowSensorManager = shadowOf(
mContext.getSystemService(SensorManager.class));
// Lux threshold levels
private final int[] mAutoBrightnessLevels = new int[]{5, 10, 15};
// Brightness values
private final int[] mAutoBrightnessLcdBacklightValuesNormal = new int[]{2, 2, 4, 14};
private final int[] mAutoBrightnessLcdBacklightValuesDoze = new int[]{2, 2, 2, 6};
@Mock
HalAdapter mHalAdapter;
@Mock
Resources mFrameworkResourcesMock;
@Mock
Resources mWearResourcesMock;
private Handler mBgHandler;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
HandlerThread bgThread = new HandlerThread("Background Thread");
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());
// Lux threshold levels
when(mFrameworkResourcesMock.getIntArray(R.array.config_autoBrightnessLevels)).thenReturn(
mAutoBrightnessLevels);
when(mFrameworkResourcesMock.getIntArray(
R.array.config_autoBrightnessLcdBacklightValues)).thenReturn(
mAutoBrightnessLcdBacklightValuesNormal);
when(mFrameworkResourcesMock.getIntArray(
R.array.config_autoBrightnessLcdBacklightValues_doze)).thenReturn(
mAutoBrightnessLcdBacklightValuesDoze);
when(mFrameworkResourcesMock.getInteger(
R.integer.config_screenBrightnessSettingDefault)).thenReturn(204);
when(mFrameworkResourcesMock.getInteger(R.integer.config_screenBrightnessDoze)).thenReturn(
60);
mShadowSensorManager.addSensor(ShadowSensor.newInstance(Sensor.TYPE_LIGHT));
setAutomaticBrightnessEnabled(true);
}
@After
public void tearDown() {
mBgHandler.getLooper().quit();
}
@Test
public void testOnBootComplete_aodOff_shouldUseAllZeroAsDim() throws RemoteException {
// Disable ambient
AmbientConfig ambientConfig = spy(new AmbientConfig(mContext.getContentResolver()));
when(ambientConfig.isAmbientEnabled()).thenReturn(false);
BrightnessOffloadController brightnessOffloadController = new BrightnessOffloadController(
mContext.getContentResolver(), mFrameworkResourcesMock,
mContext.getSystemService(SensorManager.class), mBgHandler, mHalAdapter);
// setBrightnessConfiguration be called with empty thresholds & only one brightness level
brightnessOffloadController.onBootComplete(ambientConfig);
verify(mHalAdapter).setBrightnessConfiguration(eq(false), any(),
argThat(x -> x.stream().allMatch(e -> e == 0)), any());
}
@Test
public void testOnBootComplete_shouldUseThresholdConfigured_manualBrightness()
throws RemoteException {
// Set to manual brightness
setAutomaticBrightnessEnabled(false);
// Enable ambient
AmbientConfig ambientConfig = spy(new AmbientConfig(mContext.getContentResolver()));
when(ambientConfig.isAmbientEnabled()).thenReturn(true);
BrightnessOffloadController brightnessOffloadController = new BrightnessOffloadController(
mContext.getContentResolver(), mFrameworkResourcesMock,
mContext.getSystemService(SensorManager.class), mBgHandler, mHalAdapter);
// setBrightnessConfiguration be called with empty thresholds & only one brightness level
brightnessOffloadController.onBootComplete(ambientConfig);
verify(mHalAdapter).setBrightnessConfiguration(eq(false), argThat(ArrayList::isEmpty),
argThat(x -> x.size() == 1), argThat(x -> x.size() == 1));
}
@Test
public void testOnBootComplete_shouldUseThresholdConfigured_automaticBrightness()
throws RemoteException {
// Enable ambient
AmbientConfig ambientConfig = spy(new AmbientConfig(mContext.getContentResolver()));
when(ambientConfig.isAmbientEnabled()).thenReturn(true);
BrightnessOffloadController brightnessOffloadController = new BrightnessOffloadController(
mContext.getContentResolver(), mFrameworkResourcesMock,
mContext.getSystemService(SensorManager.class), mBgHandler, mHalAdapter);
// Only test for Normal, others are deprecated.
brightnessOffloadController.onBootComplete(ambientConfig);
verify(mHalAdapter).setBrightnessConfiguration(eq(false),
eq(ArrayUtils.intArrayToShortArrayList(mAutoBrightnessLevels)),
eq(ArrayUtils.intArrayToShortArrayList(mAutoBrightnessLcdBacklightValuesDoze)),
eq(ArrayUtils.intArrayToShortArrayList(mAutoBrightnessLcdBacklightValuesNormal)));
}
@Test
public void testOnBootComplete_shouldTriggerOnAmbientConfigChanged() {
BrightnessOffloadController brightnessOffloadController = spy(
new BrightnessOffloadController(mContext.getContentResolver(),
mFrameworkResourcesMock, mContext.getSystemService(SensorManager.class),
mBgHandler, mHalAdapter));
brightnessOffloadController.onBootComplete();
verify(brightnessOffloadController).onAmbientConfigChanged();
}
@Test
public void testOnBootComplete_shouldRegisterForAmbientConfigChanges() {
AmbientConfig ambientConfig = spy(new AmbientConfig(mContext.getContentResolver()));
BrightnessOffloadController brightnessOffloadController = spy(
new BrightnessOffloadController(mContext.getContentResolver(),
mFrameworkResourcesMock, mContext.getSystemService(SensorManager.class),
mBgHandler, mHalAdapter));
brightnessOffloadController.onBootComplete(ambientConfig);
verify(brightnessOffloadController).onAmbientConfigChanged();
verify(ambientConfig).register();
verify(ambientConfig).addListener(eq(brightnessOffloadController));
}
@Test
public void testOnBootComplete_shouldRegisterForBrightnessConfigChanges() {
ContentResolver contentResolver = spy(mContext.getContentResolver());
BrightnessOffloadController brightnessOffloadController = spy(
new BrightnessOffloadController(contentResolver, mFrameworkResourcesMock,
mContext.getSystemService(SensorManager.class), mBgHandler, mHalAdapter));
brightnessOffloadController.onBootComplete();
shadowOf(mBgHandler.getLooper()).runToEndOfTasks();
verify(contentResolver, atLeastOnce()).registerContentObserver(
eq(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE)), anyBoolean(),
any());
}
private void setAutomaticBrightnessEnabled(boolean useAutomatic) {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
useAutomatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
: Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
}
}