diff options
19 files changed, 205 insertions, 1048 deletions
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java index 4af22bfac92d..b826def55e92 100644 --- a/core/java/android/accounts/ChooseAccountActivity.java +++ b/core/java/android/accounts/ChooseAccountActivity.java @@ -16,7 +16,6 @@ package android.accounts; import android.app.Activity; -import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.content.Context; import android.content.pm.PackageManager; @@ -25,8 +24,8 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.IBinder; import android.os.Parcelable; -import android.os.RemoteException; import android.os.Process; +import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; import android.view.LayoutInflater; @@ -37,6 +36,7 @@ import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; + import com.android.internal.R; import java.util.HashMap; @@ -60,6 +60,9 @@ public class ChooseAccountActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().addSystemFlags( + android.view.WindowManager.LayoutParams + .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS); mAccountManagerResponse = getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE); diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java index e3352bc85668..300fdd4ee419 100644 --- a/core/java/android/accounts/ChooseAccountTypeActivity.java +++ b/core/java/android/accounts/ChooseAccountTypeActivity.java @@ -31,6 +31,7 @@ import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; + import com.android.internal.R; import java.util.ArrayList; @@ -51,7 +52,9 @@ public class ChooseAccountTypeActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + getWindow().addSystemFlags( + android.view.WindowManager.LayoutParams + .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState=" + savedInstanceState + ")"); diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java index 4b4ef002ae06..9bf4170e767d 100644 --- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java +++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java @@ -15,11 +15,8 @@ */ package android.accounts; -import android.app.ActivityTaskManager; -import com.google.android.collect.Sets; - import android.app.Activity; -import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.content.Intent; import android.os.Bundle; import android.os.IBinder; @@ -39,6 +36,8 @@ import android.widget.TextView; import com.android.internal.R; +import com.google.android.collect.Sets; + import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; @@ -143,7 +142,9 @@ public class ChooseTypeAndAccountActivity extends Activity Log.v(TAG, "ChooseTypeAndAccountActivity.onCreate(savedInstanceState=" + savedInstanceState + ")"); } - + getWindow().addSystemFlags( + android.view.WindowManager.LayoutParams + .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); String message = null; try { diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 7a383d993389..9271d0e05fa0 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -870,76 +870,37 @@ public final class DisplayManager { public interface DeviceConfig { /** - * Key for refresh rate in the low zone defined by thresholds. + * Key for refresh rate in the zone defined by thresholds. * - * Note that the name and value don't match because they were added before we had a high - * zone to consider. * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER * @see android.R.integer#config_defaultZoneBehavior */ - String KEY_REFRESH_RATE_IN_LOW_ZONE = "refresh_rate_in_zone"; + String KEY_REFRESH_RATE_IN_ZONE = "refresh_rate_in_zone"; /** - * Key for accessing the low display brightness thresholds for the configured refresh - * rate zone. + * Key for accessing the display brightness thresholds for the configured refresh rate zone. * The value will be a pair of comma separated integers representing the minimum and maximum * thresholds of the zone, respectively, in display backlight units (i.e. [0, 255]). * - * Note that the name and value don't match because they were added before we had a high - * zone to consider. - * * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER * @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate * @hide */ - String KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS = + String KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS = "peak_refresh_rate_brightness_thresholds"; /** - * Key for accessing the low ambient brightness thresholds for the configured refresh - * rate zone. The value will be a pair of comma separated integers representing the minimum - * and maximum thresholds of the zone, respectively, in lux. - * - * Note that the name and value don't match because they were added before we had a high - * zone to consider. - * - * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER - * @see android.R.array#config_ambientThresholdsOfPeakRefreshRate - * @hide - */ - String KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS = - "peak_refresh_rate_ambient_thresholds"; - /** - * Key for refresh rate in the high zone defined by thresholds. - * - * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER - * @see android.R.integer#config_fixedRefreshRateInHighZone - */ - String KEY_REFRESH_RATE_IN_HIGH_ZONE = "refresh_rate_in_high_zone"; - - /** - * Key for accessing the display brightness thresholds for the configured refresh rate zone. - * The value will be a pair of comma separated integers representing the minimum and maximum - * thresholds of the zone, respectively, in display backlight units (i.e. [0, 255]). - * - * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER - * @see android.R.array#config_brightnessHighThresholdsOfFixedRefreshRate - * @hide - */ - String KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS = - "fixed_refresh_rate_high_display_brightness_thresholds"; - - /** * Key for accessing the ambient brightness thresholds for the configured refresh rate zone. * The value will be a pair of comma separated integers representing the minimum and maximum * thresholds of the zone, respectively, in lux. * * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER - * @see android.R.array#config_ambientHighThresholdsOfFixedRefreshRate + * @see android.R.array#config_ambientThresholdsOfPeakRefreshRate * @hide */ - String KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS = - "fixed_refresh_rate_high_ambient_brightness_thresholds"; + String KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS = + "peak_refresh_rate_ambient_thresholds"; + /** * Key for default peak refresh rate * diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index 6ed32d9c55c9..ab7d3b1b5b25 100644 --- a/core/java/android/provider/CalendarContract.java +++ b/core/java/android/provider/CalendarContract.java @@ -40,6 +40,7 @@ import android.database.DatabaseUtils; import android.net.Uri; import android.os.Build; import android.os.RemoteException; +import android.os.StrictMode; import android.text.format.DateUtils; import android.text.format.TimeMigrationUtils; import android.util.Log; @@ -2619,7 +2620,13 @@ public final class CalendarContract { intent.setData(ContentUris.withAppendedId(CalendarContract.CONTENT_URI, alarmTime)); intent.putExtra(ALARM_TIME, alarmTime); intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + + // Disable strict mode VM policy violations temporarily for intents that contain a + // content URI but don't have FLAG_GRANT_READ_URI_PERMISSION. + StrictMode.VmPolicy oldVmPolicy = StrictMode.allowVmViolations(); PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); + StrictMode.setVmPolicy(oldVmPolicy); + manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTime, pi); } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index aeba82a8ad8d..93758b6d66d6 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4179,35 +4179,6 @@ If non-positive, then the refresh rate is unchanged even if thresholds are configured. --> <integer name="config_defaultRefreshRateInZone">0</integer> - <!-- The display uses different gamma curves for different refresh rates. It's hard for panel - vendor to tune the curves to have exact same brightness for different refresh rate. So - flicker could be observed at switch time. The issue can be observed on the screen with - even full white content at the high brightness. To prevent flickering, we support fixed - refresh rates if the display and ambient brightness are equal to or above the provided - thresholds. You can define multiple threshold levels as higher brightness environments - may have lower display brightness requirements for the flickering is visible. And the - high brightness environment could have higher threshold. - For example, fixed refresh rate if - display brightness >= disp0 && ambient brightness >= amb0 - || display brightness >= disp1 && ambient brightness >= amb1 --> - <integer-array translatable="false" name="config_highDisplayBrightnessThresholdsOfFixedRefreshRate"> - <!-- - <item>disp0</item> - <item>disp1</item> - --> - </integer-array> - - <integer-array translatable="false" name="config_highAmbientBrightnessThresholdsOfFixedRefreshRate"> - <!-- - <item>amb0</item> - <item>amb1</item> - --> - </integer-array> - - <!-- Default refresh rate in the high zone defined by brightness and ambient thresholds. - If non-positive, then the refresh rate is unchanged even if thresholds are configured. --> - <integer name="config_fixedRefreshRateInHighZone">0</integer> - <!-- The type of the light sensor to be used by the display framework for things like auto-brightness. If unset, then it just gets the default sensor of type TYPE_LIGHT. --> <string name="config_displayLightSensorType" translatable="false" /> diff --git a/core/res/res/values/required_apps_managed_device.xml b/core/res/res/values/required_apps_managed_device.xml index 40db9dfbcd2c..4c5cd6861601 100644 --- a/core/res/res/values/required_apps_managed_device.xml +++ b/core/res/res/values/required_apps_managed_device.xml @@ -27,5 +27,6 @@ <item>com.android.providers.downloads</item> <item>com.android.providers.downloads.ui</item> <item>com.android.documentsui</item> + <item>com.android.cellbroadcastreceiver</item> </string-array> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 713436d195cf..fc75463a44fa 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3792,11 +3792,6 @@ <java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" /> <java-symbol type="array" name="config_ambientThresholdsOfPeakRefreshRate" /> - <!-- For fixed refresh rate displays in high brightness--> - <java-symbol type="integer" name="config_fixedRefreshRateInHighZone" /> - <java-symbol type="array" name="config_highDisplayBrightnessThresholdsOfFixedRefreshRate" /> - <java-symbol type="array" name="config_highAmbientBrightnessThresholdsOfFixedRefreshRate" /> - <!-- For Auto-Brightness --> <java-symbol type="string" name="config_displayLightSensorType" /> diff --git a/services/core/Android.bp b/services/core/Android.bp index 0beb8ff5de54..a1956476e49c 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -8,13 +8,6 @@ package { } filegroup { - name: "services.core-sources-deviceconfig-interface", - srcs: [ - "java/com/android/server/utils/DeviceConfigInterface.java" - ], -} - -filegroup { name: "services.core-sources", srcs: ["java/**/*.java"], exclude_srcs: [":connectivity-service-srcs"], diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index e30b1ebdbe2a..baa43cfd92f1 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -46,10 +46,8 @@ import android.view.DisplayInfo; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; -import com.android.internal.util.IndentingPrintWriter; import com.android.server.display.utils.AmbientFilter; import com.android.server.display.utils.AmbientFilterFactory; -import com.android.server.utils.DeviceConfigInterface; import java.io.PrintWriter; import java.util.ArrayList; @@ -66,11 +64,9 @@ public class DisplayModeDirector { private static final boolean DEBUG = false; private static final int MSG_REFRESH_RATE_RANGE_CHANGED = 1; - private static final int MSG_LOW_BRIGHTNESS_THRESHOLDS_CHANGED = 2; + private static final int MSG_BRIGHTNESS_THRESHOLDS_CHANGED = 2; private static final int MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED = 3; - private static final int MSG_REFRESH_RATE_IN_LOW_ZONE_CHANGED = 4; - private static final int MSG_REFRESH_RATE_IN_HIGH_ZONE_CHANGED = 5; - private static final int MSG_HIGH_BRIGHTNESS_THRESHOLDS_CHANGED = 6; + private static final int MSG_REFRESH_RATE_IN_ZONE_CHANGED = 4; // Special ID used to indicate that given vote is to be applied globally, rather than to a // specific display. @@ -83,13 +79,6 @@ public class DisplayModeDirector { private final Context mContext; private final DisplayModeDirectorHandler mHandler; - private final Injector mInjector; - - private final AppRequestObserver mAppRequestObserver; - private final SettingsObserver mSettingsObserver; - private final DisplayObserver mDisplayObserver; - private final DeviceConfigInterface mDeviceConfig; - private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings; // A map from the display ID to the collection of votes and their priority. The latter takes // the form of another map from the priority to the vote itself so that each priority is @@ -100,19 +89,17 @@ public class DisplayModeDirector { // A map from the display ID to the default mode of that display. private SparseArray<Display.Mode> mDefaultModeByDisplay; + private final AppRequestObserver mAppRequestObserver; + private final SettingsObserver mSettingsObserver; + private final DisplayObserver mDisplayObserver; private BrightnessObserver mBrightnessObserver; + private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings; private DesiredDisplayModeSpecsListener mDesiredDisplayModeSpecsListener; public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) { - this(context, handler, new RealInjector()); - } - - public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler, - @NonNull Injector injector) { mContext = context; mHandler = new DisplayModeDirectorHandler(handler.getLooper()); - mInjector = injector; mVotesByDisplay = new SparseArray<>(); mSupportedModesByDisplay = new SparseArray<>(); mDefaultModeByDisplay = new SparseArray<>(); @@ -121,7 +108,6 @@ public class DisplayModeDirector { mDisplayObserver = new DisplayObserver(context, handler); mBrightnessObserver = new BrightnessObserver(context, handler); mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); - mDeviceConfig = injector.getDeviceConfig(); } /** @@ -362,23 +348,6 @@ public class DisplayModeDirector { } /** - * Retrieve the Vote for the given display and priority. Intended only for testing purposes. - * - * @param displayId the display to query for - * @param priority the priority of the vote to return - * @return the vote corresponding to the given {@code displayId} and {@code priority}, - * or {@code null} if there isn't one - */ - @VisibleForTesting - @Nullable - Vote getVote(int displayId, int priority) { - synchronized (mLock) { - SparseArray<Vote> votes = getVotesLocked(displayId); - return votes.get(priority); - } - } - - /** * Print the object's state and debug information into the given stream. * * @param pw The stream to dump information to. @@ -496,17 +465,6 @@ public class DisplayModeDirector { } @VisibleForTesting - BrightnessObserver getBrightnessObserver() { - return mBrightnessObserver; - } - - @VisibleForTesting - SettingsObserver getSettingsObserver() { - return mSettingsObserver; - } - - - @VisibleForTesting DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings( float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) { synchronized (mLock) { @@ -534,35 +492,16 @@ public class DisplayModeDirector { @Override public void handleMessage(Message msg) { switch (msg.what) { - case MSG_LOW_BRIGHTNESS_THRESHOLDS_CHANGED: { - Pair<int[], int[]> thresholds = (Pair<int[], int[]>) msg.obj; - mBrightnessObserver.onDeviceConfigLowBrightnessThresholdsChanged( - thresholds.first, thresholds.second); - break; - } - - case MSG_REFRESH_RATE_IN_LOW_ZONE_CHANGED: { - int refreshRateInZone = msg.arg1; - mBrightnessObserver.onDeviceConfigRefreshRateInLowZoneChanged( - refreshRateInZone); - break; - } - - case MSG_HIGH_BRIGHTNESS_THRESHOLDS_CHANGED: { + case MSG_BRIGHTNESS_THRESHOLDS_CHANGED: Pair<int[], int[]> thresholds = (Pair<int[], int[]>) msg.obj; - mBrightnessObserver.onDeviceConfigHighBrightnessThresholdsChanged( - thresholds.first, thresholds.second); - - break; - } - - case MSG_REFRESH_RATE_IN_HIGH_ZONE_CHANGED: { - int refreshRateInZone = msg.arg1; - mBrightnessObserver.onDeviceConfigRefreshRateInHighZoneChanged( - refreshRateInZone); + if (thresholds != null) { + mBrightnessObserver.onDeviceConfigThresholdsChanged( + thresholds.first, thresholds.second); + } else { + mBrightnessObserver.onDeviceConfigThresholdsChanged(null, null); + } break; - } case MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED: Float defaultPeakRefreshRate = (Float) msg.obj; @@ -570,6 +509,12 @@ public class DisplayModeDirector { defaultPeakRefreshRate); break; + case MSG_REFRESH_RATE_IN_ZONE_CHANGED: + int refreshRateInZone = msg.arg1; + mBrightnessObserver.onDeviceConfigRefreshRateInZoneChanged( + refreshRateInZone); + break; + case MSG_REFRESH_RATE_RANGE_CHANGED: DesiredDisplayModeSpecsListener desiredDisplayModeSpecsListener = (DesiredDisplayModeSpecsListener) msg.obj; @@ -739,11 +684,10 @@ public class DisplayModeDirector { // by all other considerations. It acts to set a default frame rate for a device. public static final int PRIORITY_DEFAULT_REFRESH_RATE = 0; - // FLICKER votes for a single refresh rate like [60,60], [90,90] or null. + // LOW_BRIGHTNESS votes for a single refresh rate like [60,60], [90,90] or null. // If the higher voters result is a range, it will fix the rate to a single choice. - // It's used to avoid refresh rate switches in certain conditions which may result in the - // user seeing the display flickering when the switches occur. - public static final int PRIORITY_FLICKER = 1; + // It's used to avoid rate switch in certain conditions. + public static final int PRIORITY_LOW_BRIGHTNESS = 1; // SETTING_MIN_REFRESH_RATE is used to propose a lower bound of display refresh rate. // It votes [MIN_REFRESH_RATE, Float.POSITIVE_INFINITY] @@ -816,8 +760,8 @@ public class DisplayModeDirector { switch (priority) { case PRIORITY_DEFAULT_REFRESH_RATE: return "PRIORITY_DEFAULT_REFRESH_RATE"; - case PRIORITY_FLICKER: - return "PRIORITY_FLICKER"; + case PRIORITY_LOW_BRIGHTNESS: + return "PRIORITY_LOW_BRIGHTNESS"; case PRIORITY_USER_SETTING_MIN_REFRESH_RATE: return "PRIORITY_USER_SETTING_MIN_REFRESH_RATE"; case PRIORITY_APP_REQUEST_REFRESH_RATE: @@ -842,8 +786,7 @@ public class DisplayModeDirector { } } - @VisibleForTesting - final class SettingsObserver extends ContentObserver { + private final class SettingsObserver extends ContentObserver { private final Uri mPeakRefreshRateSetting = Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE); private final Uri mMinRefreshRateSetting = @@ -866,7 +809,8 @@ public class DisplayModeDirector { public void observe() { final ContentResolver cr = mContext.getContentResolver(); - mInjector.registerPeakRefreshRateObserver(cr, this); + cr.registerContentObserver(mPeakRefreshRateSetting, false /*notifyDescendants*/, this, + UserHandle.USER_SYSTEM); cr.registerContentObserver(mMinRefreshRateSetting, false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM); cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this, @@ -884,13 +828,6 @@ public class DisplayModeDirector { } } - public void setDefaultRefreshRate(float refreshRate) { - synchronized (mLock) { - mDefaultRefreshRate = refreshRate; - updateRefreshRateSettingLocked(); - } - } - public void onDeviceConfigDefaultPeakRefreshRateChanged(Float defaultPeakRefreshRate) { if (defaultPeakRefreshRate == null) { defaultPeakRefreshRate = (float) mContext.getResources().getInteger( @@ -1095,7 +1032,6 @@ public class DisplayModeDirector { @Override public void onDisplayChanged(int displayId) { updateDisplayModes(displayId); - // TODO: Break the coupling between DisplayObserver and BrightnessObserver. mBrightnessObserver.onDisplayChanged(displayId); } @@ -1134,16 +1070,15 @@ public class DisplayModeDirector { */ @VisibleForTesting public class BrightnessObserver extends ContentObserver { + // TODO: brightnessfloat: change this to the float setting + private final Uri mDisplayBrightnessSetting = + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); private final static int LIGHT_SENSOR_RATE_MS = 250; - private int[] mLowDisplayBrightnessThresholds; - private int[] mLowAmbientBrightnessThresholds; - private int[] mHighDisplayBrightnessThresholds; - private int[] mHighAmbientBrightnessThresholds; + private int[] mDisplayBrightnessThresholds; + private int[] mAmbientBrightnessThresholds; // valid threshold if any item from the array >= 0 - private boolean mShouldObserveDisplayLowChange; - private boolean mShouldObserveAmbientLowChange; - private boolean mShouldObserveDisplayHighChange; - private boolean mShouldObserveAmbientHighChange; + private boolean mShouldObserveDisplayChange; + private boolean mShouldObserveAmbientChange; private SensorManager mSensorManager; private Sensor mLightSensor; @@ -1151,122 +1086,46 @@ public class DisplayModeDirector { // Take it as low brightness before valid sensor data comes private float mAmbientLux = -1.0f; private AmbientFilter mAmbientFilter; - private int mBrightness = -1; private final Context mContext; - // Enable light sensor only when mShouldObserveAmbientLowChange is true or - // mShouldObserveAmbientHighChange is true, screen is on, peak refresh rate - // changeable and low power mode off. After initialization, these states will + // Enable light sensor only when mShouldObserveAmbientChange is true, screen is on, peak + // refresh rate changeable and low power mode off. After initialization, these states will // be updated from the same handler thread. - private boolean mDefaultDisplayOn = false; + private boolean mScreenOn = false; private boolean mRefreshRateChangeable = false; private boolean mLowPowerModeEnabled = false; - private int mRefreshRateInLowZone; - private int mRefreshRateInHighZone; + private int mRefreshRateInZone; BrightnessObserver(Context context, Handler handler) { super(handler); mContext = context; - mLowDisplayBrightnessThresholds = context.getResources().getIntArray( + mDisplayBrightnessThresholds = context.getResources().getIntArray( R.array.config_brightnessThresholdsOfPeakRefreshRate); - mLowAmbientBrightnessThresholds = context.getResources().getIntArray( + mAmbientBrightnessThresholds = context.getResources().getIntArray( R.array.config_ambientThresholdsOfPeakRefreshRate); - if (mLowDisplayBrightnessThresholds.length != mLowAmbientBrightnessThresholds.length) { - throw new RuntimeException("display low brightness threshold array and ambient " - + "brightness threshold array have different length: " - + "displayBrightnessThresholds=" - + Arrays.toString(mLowDisplayBrightnessThresholds) - + ", ambientBrightnessThresholds=" - + Arrays.toString(mLowAmbientBrightnessThresholds)); + if (mDisplayBrightnessThresholds.length != mAmbientBrightnessThresholds.length) { + throw new RuntimeException("display brightness threshold array and ambient " + + "brightness threshold array have different length"); } - - mHighDisplayBrightnessThresholds = context.getResources().getIntArray( - R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate); - mHighAmbientBrightnessThresholds = context.getResources().getIntArray( - R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate); - if (mHighDisplayBrightnessThresholds.length - != mHighAmbientBrightnessThresholds.length) { - throw new RuntimeException("display high brightness threshold array and ambient " - + "brightness threshold array have different length: " - + "displayBrightnessThresholds=" - + Arrays.toString(mHighDisplayBrightnessThresholds) - + ", ambientBrightnessThresholds=" - + Arrays.toString(mHighAmbientBrightnessThresholds)); - } - mRefreshRateInHighZone = context.getResources().getInteger( - R.integer.config_fixedRefreshRateInHighZone); - } - - /** - * @return the refresh to lock to when in a low brightness zone - */ - @VisibleForTesting - int getRefreshRateInLowZone() { - return mRefreshRateInLowZone; - } - - /** - * @return the display brightness thresholds for the low brightness zones - */ - @VisibleForTesting - int[] getLowDisplayBrightnessThresholds() { - return mLowDisplayBrightnessThresholds; - } - - /** - * @return the ambient brightness thresholds for the low brightness zones - */ - @VisibleForTesting - int[] getLowAmbientBrightnessThresholds() { - return mLowAmbientBrightnessThresholds; - } - - public void registerLightSensor(SensorManager sensorManager, Sensor lightSensor) { - mSensorManager = sensorManager; - mLightSensor = lightSensor; - - mSensorManager.registerListener(mLightSensorListener, - mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler); } public void observe(SensorManager sensorManager) { mSensorManager = sensorManager; - final ContentResolver cr = mContext.getContentResolver(); - mBrightness = Settings.System.getIntForUser(cr, - Settings.System.SCREEN_BRIGHTNESS, -1 /*default*/, cr.getUserId()); // DeviceConfig is accessible after system ready. - int[] lowDisplayBrightnessThresholds = - mDeviceConfigDisplaySettings.getLowDisplayBrightnessThresholds(); - int[] lowAmbientBrightnessThresholds = - mDeviceConfigDisplaySettings.getLowAmbientBrightnessThresholds(); - - if (lowDisplayBrightnessThresholds != null && lowAmbientBrightnessThresholds != null - && lowDisplayBrightnessThresholds.length - == lowAmbientBrightnessThresholds.length) { - mLowDisplayBrightnessThresholds = lowDisplayBrightnessThresholds; - mLowAmbientBrightnessThresholds = lowAmbientBrightnessThresholds; - } + int[] brightnessThresholds = mDeviceConfigDisplaySettings.getBrightnessThresholds(); + int[] ambientThresholds = mDeviceConfigDisplaySettings.getAmbientThresholds(); - - int[] highDisplayBrightnessThresholds = - mDeviceConfigDisplaySettings.getHighDisplayBrightnessThresholds(); - int[] highAmbientBrightnessThresholds = - mDeviceConfigDisplaySettings.getHighAmbientBrightnessThresholds(); - - if (highDisplayBrightnessThresholds != null && highAmbientBrightnessThresholds != null - && highDisplayBrightnessThresholds.length - == highAmbientBrightnessThresholds.length) { - mHighDisplayBrightnessThresholds = highDisplayBrightnessThresholds; - mHighAmbientBrightnessThresholds = highAmbientBrightnessThresholds; + if (brightnessThresholds != null && ambientThresholds != null + && brightnessThresholds.length == ambientThresholds.length) { + mDisplayBrightnessThresholds = brightnessThresholds; + mAmbientBrightnessThresholds = ambientThresholds; } - mRefreshRateInLowZone = mDeviceConfigDisplaySettings.getRefreshRateInLowZone(); - mRefreshRateInHighZone = mDeviceConfigDisplaySettings.getRefreshRateInHighZone(); - + mRefreshRateInZone = mDeviceConfigDisplaySettings.getRefreshRateInZone(); restartObserver(); mDeviceConfigDisplaySettings.startListening(); } @@ -1278,7 +1137,7 @@ public class DisplayModeDirector { updateSensorStatus(); if (!changeable) { // Revoke previous vote from BrightnessObserver - updateVoteLocked(Vote.PRIORITY_FLICKER, null); + updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, null); } } } @@ -1290,48 +1149,25 @@ public class DisplayModeDirector { } } - public void onDeviceConfigLowBrightnessThresholdsChanged(int[] displayThresholds, + public void onDeviceConfigThresholdsChanged(int[] brightnessThresholds, int[] ambientThresholds) { - if (displayThresholds != null && ambientThresholds != null - && displayThresholds.length == ambientThresholds.length) { - mLowDisplayBrightnessThresholds = displayThresholds; - mLowAmbientBrightnessThresholds = ambientThresholds; + if (brightnessThresholds != null && ambientThresholds != null + && brightnessThresholds.length == ambientThresholds.length) { + mDisplayBrightnessThresholds = brightnessThresholds; + mAmbientBrightnessThresholds = ambientThresholds; } else { // Invalid or empty. Use device default. - mLowDisplayBrightnessThresholds = mContext.getResources().getIntArray( + mDisplayBrightnessThresholds = mContext.getResources().getIntArray( R.array.config_brightnessThresholdsOfPeakRefreshRate); - mLowAmbientBrightnessThresholds = mContext.getResources().getIntArray( + mAmbientBrightnessThresholds = mContext.getResources().getIntArray( R.array.config_ambientThresholdsOfPeakRefreshRate); } restartObserver(); } - public void onDeviceConfigRefreshRateInLowZoneChanged(int refreshRate) { - if (refreshRate != mRefreshRateInLowZone) { - mRefreshRateInLowZone = refreshRate; - restartObserver(); - } - } - - public void onDeviceConfigHighBrightnessThresholdsChanged(int[] displayThresholds, - int[] ambientThresholds) { - if (displayThresholds != null && ambientThresholds != null - && displayThresholds.length == ambientThresholds.length) { - mHighDisplayBrightnessThresholds = displayThresholds; - mHighAmbientBrightnessThresholds = ambientThresholds; - } else { - // Invalid or empty. Use device default. - mHighDisplayBrightnessThresholds = mContext.getResources().getIntArray( - R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate); - mHighAmbientBrightnessThresholds = mContext.getResources().getIntArray( - R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate); - } - restartObserver(); - } - - public void onDeviceConfigRefreshRateInHighZoneChanged(int refreshRate) { - if (refreshRate != mRefreshRateInHighZone) { - mRefreshRateInHighZone = refreshRate; + public void onDeviceConfigRefreshRateInZoneChanged(int refreshRate) { + if (refreshRate != mRefreshRateInZone) { + mRefreshRateInZone = refreshRate; restartObserver(); } } @@ -1339,95 +1175,48 @@ public class DisplayModeDirector { public void dumpLocked(PrintWriter pw) { pw.println(" BrightnessObserver"); pw.println(" mAmbientLux: " + mAmbientLux); - pw.println(" mBrightness: " + mBrightness); - pw.println(" mDefaultDisplayOn: " + mDefaultDisplayOn); - pw.println(" mLowPowerModeEnabled: " + mLowPowerModeEnabled); - pw.println(" mRefreshRateChangeable: " + mRefreshRateChangeable); - pw.println(" mShouldObserveDisplayLowChange: " + mShouldObserveDisplayLowChange); - pw.println(" mShouldObserveAmbientLowChange: " + mShouldObserveAmbientLowChange); - pw.println(" mRefreshRateInLowZone: " + mRefreshRateInLowZone); + pw.println(" mRefreshRateInZone: " + mRefreshRateInZone); - for (int d : mLowDisplayBrightnessThresholds) { - pw.println(" mDisplayLowBrightnessThreshold: " + d); + for (int d: mDisplayBrightnessThresholds) { + pw.println(" mDisplayBrightnessThreshold: " + d); } - for (int d : mLowAmbientBrightnessThresholds) { - pw.println(" mAmbientLowBrightnessThreshold: " + d); - } - - pw.println(" mShouldObserveDisplayHighChange: " + mShouldObserveDisplayHighChange); - pw.println(" mShouldObserveAmbientHighChange: " + mShouldObserveAmbientHighChange); - pw.println(" mRefreshRateInHighZone: " + mRefreshRateInHighZone); - - for (int d : mHighDisplayBrightnessThresholds) { - pw.println(" mDisplayHighBrightnessThresholds: " + d); - } - - for (int d : mHighAmbientBrightnessThresholds) { - pw.println(" mAmbientHighBrightnessThresholds: " + d); + for (int d: mAmbientBrightnessThresholds) { + pw.println(" mAmbientBrightnessThreshold: " + d); } mLightSensorListener.dumpLocked(pw); - - if (mAmbientFilter != null) { - IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); - ipw.setIndent(" "); - mAmbientFilter.dump(ipw); - } } public void onDisplayChanged(int displayId) { if (displayId == Display.DEFAULT_DISPLAY) { - updateDefaultDisplayState(); + onScreenOn(isDefaultDisplayOn()); } } @Override public void onChange(boolean selfChange, Uri uri, int userId) { synchronized (mLock) { - final ContentResolver cr = mContext.getContentResolver(); - int brightness = Settings.System.getIntForUser(cr, - Settings.System.SCREEN_BRIGHTNESS, -1 /*default*/, cr.getUserId()); - if (brightness != mBrightness) { - mBrightness = brightness; - onBrightnessChangedLocked(); - } + onBrightnessChangedLocked(); } } private void restartObserver() { - final ContentResolver cr = mContext.getContentResolver(); + mShouldObserveDisplayChange = checkShouldObserve(mDisplayBrightnessThresholds); + mShouldObserveAmbientChange = checkShouldObserve(mAmbientBrightnessThresholds); - if (mRefreshRateInLowZone > 0) { - mShouldObserveDisplayLowChange = hasValidThreshold( - mLowDisplayBrightnessThresholds); - mShouldObserveAmbientLowChange = hasValidThreshold( - mLowAmbientBrightnessThresholds); - } else { - mShouldObserveDisplayLowChange = false; - mShouldObserveAmbientLowChange = false; - } - - if (mRefreshRateInHighZone > 0) { - mShouldObserveDisplayHighChange = hasValidThreshold( - mHighDisplayBrightnessThresholds); - mShouldObserveAmbientHighChange = hasValidThreshold( - mHighAmbientBrightnessThresholds); - } else { - mShouldObserveDisplayHighChange = false; - mShouldObserveAmbientHighChange = false; - } - - if (mShouldObserveDisplayLowChange || mShouldObserveDisplayHighChange) { + final ContentResolver cr = mContext.getContentResolver(); + if (mShouldObserveDisplayChange) { // Content Service does not check if an listener has already been registered. // To ensure only one listener is registered, force an unregistration first. - mInjector.unregisterBrightnessObserver(cr, this); - mInjector.registerBrightnessObserver(cr, this); + cr.unregisterContentObserver(this); + cr.registerContentObserver(mDisplayBrightnessSetting, + false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM); } else { - mInjector.unregisterBrightnessObserver(cr, this); + cr.unregisterContentObserver(this); } - if (mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange) { + if (mShouldObserveAmbientChange) { Resources resources = mContext.getResources(); String lightSensorType = resources.getString( com.android.internal.R.string.config_displayLightSensorType); @@ -1453,6 +1242,8 @@ public class DisplayModeDirector { mAmbientFilter = AmbientFilterFactory.createBrightnessFilter(TAG, res); mLightSensor = lightSensor; + + onScreenOn(isDefaultDisplayOn()); } } else { mAmbientFilter = null; @@ -1471,7 +1262,11 @@ public class DisplayModeDirector { * Checks to see if at least one value is positive, in which case it is necessary to listen * to value changes. */ - private boolean hasValidThreshold(int[] a) { + private boolean checkShouldObserve(int[] a) { + if (mRefreshRateInZone <= 0) { + return false; + } + for (int d: a) { if (d >= 0) { return true; @@ -1481,13 +1276,13 @@ public class DisplayModeDirector { return false; } - private boolean isInsideLowZone(int brightness, float lux) { - for (int i = 0; i < mLowDisplayBrightnessThresholds.length; i++) { - int disp = mLowDisplayBrightnessThresholds[i]; - int ambi = mLowAmbientBrightnessThresholds[i]; + private boolean isInsideZone(int brightness, float lux) { + for (int i = 0; i < mDisplayBrightnessThresholds.length; i++) { + int disp = mDisplayBrightnessThresholds[i]; + int ambi = mAmbientBrightnessThresholds[i]; if (disp >= 0 && ambi >= 0) { - if (brightness <= disp && lux <= ambi) { + if (brightness <= disp && mAmbientLux <= ambi) { return true; } } else if (disp >= 0) { @@ -1495,30 +1290,7 @@ public class DisplayModeDirector { return true; } } else if (ambi >= 0) { - if (lux <= ambi) { - return true; - } - } - } - - return false; - } - - private boolean isInsideHighZone(int brightness, float lux) { - for (int i = 0; i < mHighDisplayBrightnessThresholds.length; i++) { - int disp = mHighDisplayBrightnessThresholds[i]; - int ambi = mHighAmbientBrightnessThresholds[i]; - - if (disp >= 0 && ambi >= 0) { - if (brightness >= disp && lux >= ambi) { - return true; - } - } else if (disp >= 0) { - if (brightness >= disp) { - return true; - } - } else if (ambi >= 0) { - if (lux >= ambi) { + if (mAmbientLux <= ambi) { return true; } } @@ -1526,54 +1298,27 @@ public class DisplayModeDirector { return false; } + // TODO: brightnessfloat: make it use float not int private void onBrightnessChangedLocked() { - Vote vote = null; - - if (mBrightness < 0) { - // Either the setting isn't available or we shouldn't be observing yet anyways. - // Either way, just bail out since there's nothing we can do here. - return; - } + int brightness = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS, -1); - boolean insideLowZone = hasValidLowZone() && isInsideLowZone(mBrightness, mAmbientLux); - if (insideLowZone) { - vote = Vote.forRefreshRates(mRefreshRateInLowZone, mRefreshRateInLowZone); - } - - boolean insideHighZone = hasValidHighZone() - && isInsideHighZone(mBrightness, mAmbientLux); - if (insideHighZone) { - vote = Vote.forRefreshRates(mRefreshRateInHighZone, mRefreshRateInHighZone); + Vote vote = null; + boolean insideZone = isInsideZone(brightness, mAmbientLux); + if (insideZone) { + vote = Vote.forRefreshRates(mRefreshRateInZone, mRefreshRateInZone); } if (DEBUG) { - Slog.d(TAG, "Display brightness " + mBrightness + ", ambient lux " + mAmbientLux - + ", Vote " + vote); + Slog.d(TAG, "Display brightness " + brightness + ", ambient lux " + mAmbientLux + + ", Vote " + vote); } - updateVoteLocked(Vote.PRIORITY_FLICKER, vote); - } - - private boolean hasValidLowZone() { - return mRefreshRateInLowZone > 0 - && (mShouldObserveDisplayLowChange || mShouldObserveAmbientLowChange); - } - - private boolean hasValidHighZone() { - return mRefreshRateInHighZone > 0 - && (mShouldObserveDisplayHighChange || mShouldObserveAmbientHighChange); + updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote); } - private void updateDefaultDisplayState() { - Display display = mContext.getSystemService(DisplayManager.class) - .getDisplay(Display.DEFAULT_DISPLAY); - boolean defaultDisplayOn = display != null && display.getState() != Display.STATE_OFF; - setDefaultDisplayState(defaultDisplayOn); - } - - @VisibleForTesting - public void setDefaultDisplayState(boolean on) { - if (mDefaultDisplayOn != on) { - mDefaultDisplayOn = on; + private void onScreenOn(boolean on) { + if (mScreenOn != on) { + mScreenOn = on; updateSensorStatus(); } } @@ -1583,8 +1328,8 @@ public class DisplayModeDirector { return; } - if ((mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange) - && isDeviceActive() && !mLowPowerModeEnabled && mRefreshRateChangeable) { + if (mShouldObserveAmbientChange && mScreenOn && !mLowPowerModeEnabled + && mRefreshRateChangeable) { mSensorManager.registerListener(mLightSensorListener, mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler); } else { @@ -1593,8 +1338,11 @@ public class DisplayModeDirector { } } - private boolean isDeviceActive() { - return mDefaultDisplayOn && mInjector.isDeviceInteractive(mContext); + private boolean isDefaultDisplayOn() { + final Display display = mContext.getSystemService(DisplayManager.class) + .getDisplay(Display.DEFAULT_DISPLAY); + return display.getState() != Display.STATE_OFF + && mContext.getSystemService(PowerManager.class).isInteractive(); } private final class LightSensorEventListener implements SensorEventListener { @@ -1612,33 +1360,23 @@ public class DisplayModeDirector { Slog.d(TAG, "On sensor changed: " + mLastSensorData); } - boolean lowZoneChanged = isDifferentZone(mLastSensorData, mAmbientLux, - mLowAmbientBrightnessThresholds); - boolean highZoneChanged = isDifferentZone(mLastSensorData, mAmbientLux, - mHighAmbientBrightnessThresholds); - if ((lowZoneChanged && mLastSensorData < mAmbientLux) - || (highZoneChanged && mLastSensorData > mAmbientLux)) { - // Easier to see flicker at lower brightness environment or high brightness - // environment. Forget the history to get immediate response. - if (mAmbientFilter != null) { - mAmbientFilter.clear(); - } + boolean zoneChanged = isDifferentZone(mLastSensorData, mAmbientLux); + if (zoneChanged && mLastSensorData < mAmbientLux) { + // Easier to see flicker at lower brightness environment. Forget the history to + // get immediate response. + mAmbientFilter.clear(); } long now = SystemClock.uptimeMillis(); - if (mAmbientFilter != null) { - mAmbientFilter.addValue(now, mLastSensorData); - } + mAmbientFilter.addValue(now, mLastSensorData); mHandler.removeCallbacks(mInjectSensorEventRunnable); processSensorData(now); - if ((lowZoneChanged && mLastSensorData > mAmbientLux) - || (highZoneChanged && mLastSensorData < mAmbientLux)) { + if (zoneChanged && mLastSensorData > mAmbientLux) { // Sensor may not report new event if there is no brightness change. // Need to keep querying the temporal filter for the latest estimation, - // until sensor readout and filter estimation are in the same zone or - // is interrupted by a new sensor event. + // until enter in higher lux zone or is interrupted by a new sensor event. mHandler.postDelayed(mInjectSensorEventRunnable, INJECT_EVENTS_INTERVAL_MS); } } @@ -1653,19 +1391,17 @@ public class DisplayModeDirector { } private void processSensorData(long now) { - if (mAmbientFilter != null) { - mAmbientLux = mAmbientFilter.getEstimate(now); - } else { - mAmbientLux = mLastSensorData; - } + mAmbientLux = mAmbientFilter.getEstimate(now); synchronized (mLock) { onBrightnessChangedLocked(); } } - private boolean isDifferentZone(float lux1, float lux2, int[] luxThresholds) { - for (final float boundary : luxThresholds) { + private boolean isDifferentZone(float lux1, float lux2) { + for (int z = 0; z < mAmbientBrightnessThresholds.length; z++) { + final float boundary = mAmbientBrightnessThresholds[z]; + // Test each boundary. See if the current value and the new value are at // different sides. if ((lux1 <= boundary && lux2 > boundary) @@ -1685,10 +1421,7 @@ public class DisplayModeDirector { processSensorData(now); // Inject next event if there is a possible zone change. - if (isDifferentZone(mLastSensorData, mAmbientLux, - mLowAmbientBrightnessThresholds) - || isDifferentZone(mLastSensorData, mAmbientLux, - mHighAmbientBrightnessThresholds)) { + if (isDifferentZone(mLastSensorData, mAmbientLux)) { mHandler.postDelayed(mInjectSensorEventRunnable, INJECT_EVENTS_INTERVAL_MS); } } @@ -1701,75 +1434,33 @@ public class DisplayModeDirector { } public void startListening() { - mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, BackgroundThread.getExecutor(), this); } /* * Return null if no such property or wrong format (not comma separated integers). */ - public int[] getLowDisplayBrightnessThresholds() { + public int[] getBrightnessThresholds() { return getIntArrayProperty( DisplayManager.DeviceConfig. - KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS); + KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS); } /* * Return null if no such property or wrong format (not comma separated integers). */ - public int[] getLowAmbientBrightnessThresholds() { + public int[] getAmbientThresholds() { return getIntArrayProperty( DisplayManager.DeviceConfig. - KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS); - } - - public int getRefreshRateInLowZone() { - int defaultRefreshRateInZone = mContext.getResources().getInteger( - R.integer.config_defaultRefreshRateInZone); - - int refreshRate = mDeviceConfig.getInt( - DeviceConfig.NAMESPACE_DISPLAY_MANAGER, - DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE, - defaultRefreshRateInZone); - - return refreshRate; - } - - /* - * Return null if no such property or wrong format (not comma separated integers). - */ - public int[] getHighDisplayBrightnessThresholds() { - return getIntArrayProperty( - DisplayManager.DeviceConfig - .KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS); - } - - /* - * Return null if no such property or wrong format (not comma separated integers). - */ - public int[] getHighAmbientBrightnessThresholds() { - return getIntArrayProperty( - DisplayManager.DeviceConfig - .KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS); - } - - public int getRefreshRateInHighZone() { - int defaultRefreshRateInZone = mContext.getResources().getInteger( - R.integer.config_fixedRefreshRateInHighZone); - - int refreshRate = mDeviceConfig.getInt( - DeviceConfig.NAMESPACE_DISPLAY_MANAGER, - DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE, - defaultRefreshRateInZone); - - return refreshRate; + KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS); } /* * Return null if no such property */ public Float getDefaultPeakRefreshRate() { - float defaultPeakRefreshRate = mDeviceConfig.getFloat( + float defaultPeakRefreshRate = DeviceConfig.getFloat( DeviceConfig.NAMESPACE_DISPLAY_MANAGER, DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_DEFAULT, -1); @@ -1779,35 +1470,36 @@ public class DisplayModeDirector { return defaultPeakRefreshRate; } - @Override - public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { - Float defaultPeakRefreshRate = getDefaultPeakRefreshRate(); - mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED, - defaultPeakRefreshRate).sendToTarget(); + public int getRefreshRateInZone() { + int defaultRefreshRateInZone = mContext.getResources().getInteger( + R.integer.config_defaultRefreshRateInZone); - int[] lowDisplayBrightnessThresholds = getLowDisplayBrightnessThresholds(); - int[] lowAmbientBrightnessThresholds = getLowAmbientBrightnessThresholds(); - int refreshRateInLowZone = getRefreshRateInLowZone(); + int refreshRate = DeviceConfig.getInt( + DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_ZONE, + defaultRefreshRateInZone); - mHandler.obtainMessage(MSG_LOW_BRIGHTNESS_THRESHOLDS_CHANGED, - new Pair<>(lowDisplayBrightnessThresholds, lowAmbientBrightnessThresholds)) - .sendToTarget(); - mHandler.obtainMessage(MSG_REFRESH_RATE_IN_LOW_ZONE_CHANGED, refreshRateInLowZone, 0) - .sendToTarget(); + return refreshRate; + } - int[] highDisplayBrightnessThresholds = getHighDisplayBrightnessThresholds(); - int[] highAmbientBrightnessThresholds = getHighAmbientBrightnessThresholds(); - int refreshRateInHighZone = getRefreshRateInHighZone(); + @Override + public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { + int[] brightnessThresholds = getBrightnessThresholds(); + int[] ambientThresholds = getAmbientThresholds(); + Float defaultPeakRefreshRate = getDefaultPeakRefreshRate(); + int refreshRateInZone = getRefreshRateInZone(); - mHandler.obtainMessage(MSG_HIGH_BRIGHTNESS_THRESHOLDS_CHANGED, - new Pair<>(highDisplayBrightnessThresholds, highAmbientBrightnessThresholds)) - .sendToTarget(); - mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HIGH_ZONE_CHANGED, refreshRateInHighZone, 0) + mHandler.obtainMessage(MSG_BRIGHTNESS_THRESHOLDS_CHANGED, + new Pair<int[], int[]>(brightnessThresholds, ambientThresholds)) .sendToTarget(); + mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED, + defaultPeakRefreshRate).sendToTarget(); + mHandler.obtainMessage(MSG_REFRESH_RATE_IN_ZONE_CHANGED, refreshRateInZone, + 0).sendToTarget(); } private int[] getIntArrayProperty(String prop) { - String strArray = mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, prop, + String strArray = DeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, prop, null); if (strArray != null) { @@ -1834,59 +1526,4 @@ public class DisplayModeDirector { } } - interface Injector { - // TODO: brightnessfloat: change this to the float setting - Uri DISPLAY_BRIGHTNESS_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); - Uri PEAK_REFRESH_RATE_URI = Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE); - - @NonNull - DeviceConfigInterface getDeviceConfig(); - - void registerBrightnessObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer); - - void unregisterBrightnessObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer); - - void registerPeakRefreshRateObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer); - - boolean isDeviceInteractive(@NonNull Context context); - } - - @VisibleForTesting - static class RealInjector implements Injector { - - @Override - @NonNull - public DeviceConfigInterface getDeviceConfig() { - return DeviceConfigInterface.REAL; - } - - @Override - public void registerBrightnessObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer) { - cr.registerContentObserver(DISPLAY_BRIGHTNESS_URI, false /*notifyDescendants*/, - observer, UserHandle.USER_SYSTEM); - } - - @Override - public void unregisterBrightnessObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer) { - cr.unregisterContentObserver(observer); - } - - @Override - public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer) { - cr.registerContentObserver(PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/, - observer, UserHandle.USER_SYSTEM); - } - - @Override - public boolean isDeviceInteractive(@NonNull Context ctx) { - return ctx.getSystemService(PowerManager.class).isInteractive(); - } - } - } diff --git a/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java b/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java index e925b054a92b..aac6b2544c4f 100644 --- a/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java +++ b/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java @@ -27,7 +27,7 @@ import android.util.ArraySet; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; -import com.android.server.utils.DeviceConfigInterface; +import com.android.server.wm.utils.DeviceConfigInterface; import java.io.PrintWriter; diff --git a/services/core/java/com/android/server/wm/WindowManagerConstants.java b/services/core/java/com/android/server/wm/WindowManagerConstants.java index a5ebf9ac74b9..b0c5dbc6cca3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerConstants.java +++ b/services/core/java/com/android/server/wm/WindowManagerConstants.java @@ -23,7 +23,7 @@ import android.provider.AndroidDeviceConfig; import android.provider.DeviceConfig; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.utils.DeviceConfigInterface; +import com.android.server.wm.utils.DeviceConfigInterface; import java.io.PrintWriter; import java.util.Objects; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index d9594a40bde3..b7a2eb3c705d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -282,8 +282,8 @@ import com.android.server.policy.WindowManagerPolicy.ScreenOffListener; import com.android.server.power.ShutdownThread; import com.android.server.protolog.ProtoLogImpl; import com.android.server.protolog.common.ProtoLog; -import com.android.server.utils.DeviceConfigInterface; import com.android.server.utils.PriorityDump; +import com.android.server.wm.utils.DeviceConfigInterface; import java.io.BufferedWriter; import java.io.DataInputStream; diff --git a/services/core/java/com/android/server/utils/DeviceConfigInterface.java b/services/core/java/com/android/server/wm/utils/DeviceConfigInterface.java index ff609031b57c..ab7e7f63cafd 100644 --- a/services/core/java/com/android/server/utils/DeviceConfigInterface.java +++ b/services/core/java/com/android/server/wm/utils/DeviceConfigInterface.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.utils; +package com.android.server.wm.utils; import android.annotation.NonNull; import android.annotation.Nullable; @@ -54,11 +54,6 @@ public interface DeviceConfigInterface { boolean getBoolean(@NonNull String namespace, @NonNull String name, boolean defaultValue); /** - * @see DeviceConfig#getFloat - */ - float getFloat(@NonNull String namespace, @NonNull String name, float defaultValue); - - /** * @see DeviceConfig#addOnPropertiesChangedListener */ void addOnPropertiesChangedListener(@NonNull String namespace, @NonNull Executor executor, @@ -101,12 +96,6 @@ public interface DeviceConfigInterface { } @Override - public float getFloat(@NonNull String namespace, @NonNull String name, - float defaultValue) { - return DeviceConfig.getFloat(namespace, name, defaultValue); - } - - @Override public void addOnPropertiesChangedListener(String namespace, Executor executor, DeviceConfig.OnPropertiesChangedListener listener) { DeviceConfig.addOnPropertiesChangedListener(namespace, executor, listener); diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index 11d050c0dc7e..08e2def8d10d 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -57,6 +57,7 @@ android_test { // TODO: remove once Android migrates to JUnit 4.12, // which provides assertThrows "testng", + ], aidl: { @@ -118,7 +119,6 @@ java_library { "utils/**/*.java", "utils/**/*.kt", "utils-mockito/**/*.kt", - ":services.core-sources-deviceconfig-interface", ], static_libs: [ "junit", @@ -135,7 +135,6 @@ java_library { "utils/**/*.java", "utils/**/*.kt", "utils-mockito/**/*.kt", - ":services.core-sources-deviceconfig-interface", ], static_libs: [ "junit", diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java index c467ee949aeb..43a396d8e5d7 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java @@ -16,99 +16,49 @@ package com.android.server.display; -import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS; -import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS; -import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS; -import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS; -import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE; -import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE; - -import static com.android.server.display.DisplayModeDirector.Vote.PRIORITY_FLICKER; - -import static com.google.common.truth.Truth.assertThat; - import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import android.annotation.NonNull; -import android.content.ContentResolver; import android.content.Context; -import android.content.ContextWrapper; -import android.database.ContentObserver; -import android.hardware.Sensor; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; import android.os.Handler; import android.os.Looper; -import android.provider.DeviceConfig; -import android.provider.Settings; -import android.test.mock.MockContentResolver; -import android.util.Slog; import android.util.SparseArray; import android.view.Display; -import androidx.test.core.app.ApplicationProvider; +import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.util.Preconditions; -import com.android.internal.util.test.FakeSettingsProvider; -import com.android.internal.util.test.FakeSettingsProviderRule; import com.android.server.display.DisplayModeDirector.BrightnessObserver; import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs; import com.android.server.display.DisplayModeDirector.Vote; -import com.android.server.testutils.FakeDeviceConfigInterface; import com.google.common.truth.Truth; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - @SmallTest @RunWith(AndroidJUnit4.class) public class DisplayModeDirectorTest { // The tolerance within which we consider something approximately equals. - private static final String TAG = "DisplayModeDirectorTest"; - private static final boolean DEBUG = false; private static final float FLOAT_TOLERANCE = 0.01f; private Context mContext; - private FakesInjector mInjector; - private Handler mHandler; - @Rule - public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule(); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); - final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext); - when(mContext.getContentResolver()).thenReturn(resolver); - mInjector = new FakesInjector(); - mHandler = new Handler(Looper.getMainLooper()); + mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); } private DisplayModeDirector createDirectorFromRefreshRateArray( float[] refreshRates, int baseModeId) { DisplayModeDirector director = - new DisplayModeDirector(mContext, mHandler, mInjector); + new DisplayModeDirector(mContext, new Handler(Looper.getMainLooper())); int displayId = 0; Display.Mode[] modes = new Display.Mode[refreshRates.length]; for (int i = 0; i < refreshRates.length; i++) { @@ -209,9 +159,9 @@ public class DisplayModeDirectorTest { } @Test - public void testFlickerHasLowerPriorityThanUser() { - assertTrue(PRIORITY_FLICKER < Vote.PRIORITY_APP_REQUEST_REFRESH_RATE); - assertTrue(PRIORITY_FLICKER < Vote.PRIORITY_APP_REQUEST_SIZE); + public void testBrightnessHasLowerPriorityThanUser() { + assertTrue(Vote.PRIORITY_LOW_BRIGHTNESS < Vote.PRIORITY_APP_REQUEST_REFRESH_RATE); + assertTrue(Vote.PRIORITY_LOW_BRIGHTNESS < Vote.PRIORITY_APP_REQUEST_SIZE); int displayId = 0; DisplayModeDirector director = createDirectorFromFpsRange(60, 90); @@ -219,7 +169,7 @@ public class DisplayModeDirectorTest { SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); votesByDisplay.put(displayId, votes); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90)); - votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60)); + votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); @@ -227,7 +177,7 @@ public class DisplayModeDirectorTest { votes.clear(); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90)); - votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(90, 90)); + votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(90, 90)); director.injectVotesByDisplay(votesByDisplay); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); @@ -235,7 +185,7 @@ public class DisplayModeDirectorTest { votes.clear(); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(90, 90)); - votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60)); + votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); @@ -243,7 +193,7 @@ public class DisplayModeDirectorTest { votes.clear(); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 60)); - votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(90, 90)); + votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(90, 90)); director.injectVotesByDisplay(votesByDisplay); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); @@ -252,10 +202,10 @@ public class DisplayModeDirectorTest { @Test public void testAppRequestRefreshRateRange() { - // Confirm that the app request range doesn't include flicker or min refresh rate settings, - // but does include everything else. + // Confirm that the app request range doesn't include low brightness or min refresh rate + // settings, but does include everything else. assertTrue( - PRIORITY_FLICKER < Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF); + Vote.PRIORITY_LOW_BRIGHTNESS < Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF); assertTrue(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE < Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF); assertTrue(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE @@ -266,7 +216,7 @@ public class DisplayModeDirectorTest { SparseArray<Vote> votes = new SparseArray<>(); SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); votesByDisplay.put(displayId, votes); - votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60)); + votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); @@ -352,343 +302,4 @@ public class DisplayModeDirectorTest { verifyBrightnessObserverCall(director, 90, 90, 0, 90, 90); verifyBrightnessObserverCall(director, 120, 90, 0, 120, 90); } - - @Test - public void testBrightnessObserverGetsUpdatedRefreshRatesForZone() { - DisplayModeDirector director = - createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, /* baseModeId= */ 0); - SensorManager sensorManager = createMockSensorManager(createLightSensor()); - - final int initialRefreshRate = 60; - mInjector.getDeviceConfig().setRefreshRateInLowZone(initialRefreshRate); - director.start(sensorManager); - assertThat(director.getBrightnessObserver().getRefreshRateInLowZone()) - .isEqualTo(initialRefreshRate); - - final int updatedRefreshRate = 90; - mInjector.getDeviceConfig().setRefreshRateInLowZone(updatedRefreshRate); - // Need to wait for the property change to propagate to the main thread. - waitForIdleSync(); - assertThat(director.getBrightnessObserver().getRefreshRateInLowZone()) - .isEqualTo(updatedRefreshRate); - } - - @Test - public void testBrightnessObserverThresholdsInZone() { - DisplayModeDirector director = - createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, /* baseModeId= */ 0); - SensorManager sensorManager = createMockSensorManager(createLightSensor()); - - final int[] initialDisplayThresholds = { 10 }; - final int[] initialAmbientThresholds = { 20 }; - - final FakeDeviceConfig config = mInjector.getDeviceConfig(); - config.setLowDisplayBrightnessThresholds(initialDisplayThresholds); - config.setLowAmbientBrightnessThresholds(initialAmbientThresholds); - director.start(sensorManager); - - assertThat(director.getBrightnessObserver().getLowDisplayBrightnessThresholds()) - .isEqualTo(initialDisplayThresholds); - assertThat(director.getBrightnessObserver().getLowAmbientBrightnessThresholds()) - .isEqualTo(initialAmbientThresholds); - - final int[] updatedDisplayThresholds = { 9, 14 }; - final int[] updatedAmbientThresholds = { -1, 19 }; - config.setLowDisplayBrightnessThresholds(updatedDisplayThresholds); - config.setLowAmbientBrightnessThresholds(updatedAmbientThresholds); - // Need to wait for the property change to propagate to the main thread. - waitForIdleSync(); - assertThat(director.getBrightnessObserver().getLowDisplayBrightnessThresholds()) - .isEqualTo(updatedDisplayThresholds); - assertThat(director.getBrightnessObserver().getLowAmbientBrightnessThresholds()) - .isEqualTo(updatedAmbientThresholds); - } - - @Test - public void testLockFpsForLowZone() throws Exception { - DisplayModeDirector director = - createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0); - setPeakRefreshRate(90); - director.getSettingsObserver().setDefaultRefreshRate(90); - director.getBrightnessObserver().setDefaultDisplayState(true); - - final FakeDeviceConfig config = mInjector.getDeviceConfig(); - config.setRefreshRateInLowZone(90); - config.setLowDisplayBrightnessThresholds(new int[] { 10 }); - config.setLowAmbientBrightnessThresholds(new int[] { 20 }); - - Sensor lightSensor = createLightSensor(); - SensorManager sensorManager = createMockSensorManager(lightSensor); - - director.start(sensorManager); - - ArgumentCaptor<SensorEventListener> listenerCaptor = - ArgumentCaptor.forClass(SensorEventListener.class); - Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1))) - .registerListener( - listenerCaptor.capture(), - eq(lightSensor), - anyInt(), - any(Handler.class)); - SensorEventListener listener = listenerCaptor.getValue(); - - setBrightness(10); - // Sensor reads 20 lux, - listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 20 /*lux*/)); - - Vote vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER); - assertVoteForRefreshRateLocked(vote, 90 /*fps*/); - - setBrightness(125); - // Sensor reads 1000 lux, - listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 1000 /*lux*/)); - - vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER); - assertThat(vote).isNull(); - } - - @Test - public void testLockFpsForHighZone() throws Exception { - DisplayModeDirector director = - createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0); - setPeakRefreshRate(90 /*fps*/); - director.getSettingsObserver().setDefaultRefreshRate(90); - director.getBrightnessObserver().setDefaultDisplayState(true); - - final FakeDeviceConfig config = mInjector.getDeviceConfig(); - config.setRefreshRateInHighZone(60); - config.setHighDisplayBrightnessThresholds(new int[] { 255 }); - config.setHighAmbientBrightnessThresholds(new int[] { 8000 }); - - Sensor lightSensor = createLightSensor(); - SensorManager sensorManager = createMockSensorManager(lightSensor); - - director.start(sensorManager); - - ArgumentCaptor<SensorEventListener> listenerCaptor = - ArgumentCaptor.forClass(SensorEventListener.class); - Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1))) - .registerListener( - listenerCaptor.capture(), - eq(lightSensor), - anyInt(), - any(Handler.class)); - SensorEventListener listener = listenerCaptor.getValue(); - - setBrightness(100); - // Sensor reads 2000 lux, - listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 2000)); - - Vote vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER); - assertThat(vote).isNull(); - - setBrightness(255); - // Sensor reads 9000 lux, - listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 9000)); - - vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER); - assertVoteForRefreshRateLocked(vote, 60 /*fps*/); - } - - private void assertVoteForRefreshRateLocked(Vote vote, float refreshRate) { - assertThat(vote).isNotNull(); - final DisplayModeDirector.RefreshRateRange expectedRange = - new DisplayModeDirector.RefreshRateRange(refreshRate, refreshRate); - assertThat(vote.refreshRateRange).isEqualTo(expectedRange); - } - - private static class FakeDeviceConfig extends FakeDeviceConfigInterface { - @Override - public String getProperty(String namespace, String name) { - Preconditions.checkArgument(DeviceConfig.NAMESPACE_DISPLAY_MANAGER.equals(namespace)); - return super.getProperty(namespace, name); - } - - @Override - public void addOnPropertiesChangedListener( - String namespace, - Executor executor, - DeviceConfig.OnPropertiesChangedListener listener) { - Preconditions.checkArgument(DeviceConfig.NAMESPACE_DISPLAY_MANAGER.equals(namespace)); - super.addOnPropertiesChangedListener(namespace, executor, listener); - } - - void setRefreshRateInLowZone(int fps) { - putPropertyAndNotify( - DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_REFRESH_RATE_IN_LOW_ZONE, - String.valueOf(fps)); - } - - void setLowDisplayBrightnessThresholds(int[] brightnessThresholds) { - String thresholds = toPropertyValue(brightnessThresholds); - - if (DEBUG) { - Slog.e(TAG, "Brightness Thresholds = " + thresholds); - } - - putPropertyAndNotify( - DeviceConfig.NAMESPACE_DISPLAY_MANAGER, - KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS, - thresholds); - } - - void setLowAmbientBrightnessThresholds(int[] ambientThresholds) { - String thresholds = toPropertyValue(ambientThresholds); - - if (DEBUG) { - Slog.e(TAG, "Ambient Thresholds = " + thresholds); - } - - putPropertyAndNotify( - DeviceConfig.NAMESPACE_DISPLAY_MANAGER, - KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS, - thresholds); - } - - void setRefreshRateInHighZone(int fps) { - putPropertyAndNotify( - DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_REFRESH_RATE_IN_HIGH_ZONE, - String.valueOf(fps)); - } - - void setHighDisplayBrightnessThresholds(int[] brightnessThresholds) { - String thresholds = toPropertyValue(brightnessThresholds); - - if (DEBUG) { - Slog.e(TAG, "Brightness Thresholds = " + thresholds); - } - - putPropertyAndNotify( - DeviceConfig.NAMESPACE_DISPLAY_MANAGER, - KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS, - thresholds); - } - - void setHighAmbientBrightnessThresholds(int[] ambientThresholds) { - String thresholds = toPropertyValue(ambientThresholds); - - if (DEBUG) { - Slog.e(TAG, "Ambient Thresholds = " + thresholds); - } - - putPropertyAndNotify( - DeviceConfig.NAMESPACE_DISPLAY_MANAGER, - KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS, - thresholds); - } - - @NonNull - private static String toPropertyValue(@NonNull int[] intArray) { - return Arrays.stream(intArray) - .mapToObj(Integer::toString) - .collect(Collectors.joining(",")); - } - } - - private void setBrightness(int brightness) { - Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, - brightness); - mInjector.notifyBrightnessChanged(); - waitForIdleSync(); - } - - private void setPeakRefreshRate(float fps) { - Settings.System.putFloat(mContext.getContentResolver(), Settings.System.PEAK_REFRESH_RATE, - fps); - mInjector.notifyPeakRefreshRateChanged(); - waitForIdleSync(); - } - - private static SensorManager createMockSensorManager(Sensor... sensors) { - SensorManager sensorManager = Mockito.mock(SensorManager.class); - when(sensorManager.getSensorList(anyInt())).then((invocation) -> { - List<Sensor> requestedSensors = new ArrayList<>(); - int type = invocation.getArgument(0); - for (Sensor sensor : sensors) { - if (sensor.getType() == type || type == Sensor.TYPE_ALL) { - requestedSensors.add(sensor); - } - } - return requestedSensors; - }); - - when(sensorManager.getDefaultSensor(anyInt())).then((invocation) -> { - int type = invocation.getArgument(0); - for (Sensor sensor : sensors) { - if (sensor.getType() == type) { - return sensor; - } - } - return null; - }); - return sensorManager; - } - - private static Sensor createLightSensor() { - try { - return TestUtils.createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT); - } catch (Exception e) { - // There's nothing we can do if this fails, just throw a RuntimeException so that we - // don't have to mark every function that might call this as throwing Exception - throw new RuntimeException("Failed to create a light sensor", e); - } - } - - private void waitForIdleSync() { - mHandler.runWithScissors(() -> { }, 500 /*timeout*/); - } - - static class FakesInjector implements DisplayModeDirector.Injector { - private final FakeDeviceConfig mDeviceConfig; - private ContentObserver mBrightnessObserver; - private ContentObserver mPeakRefreshRateObserver; - - FakesInjector() { - mDeviceConfig = new FakeDeviceConfig(); - } - - @NonNull - public FakeDeviceConfig getDeviceConfig() { - return mDeviceConfig; - } - - @Override - public void registerBrightnessObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer) { - if (mBrightnessObserver != null) { - throw new IllegalStateException("Tried to register a second brightness observer"); - } - mBrightnessObserver = observer; - } - - @Override - public void unregisterBrightnessObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer) { - mBrightnessObserver = null; - } - - void notifyBrightnessChanged() { - if (mBrightnessObserver != null) { - mBrightnessObserver.dispatchChange(false /*selfChange*/, DISPLAY_BRIGHTNESS_URI); - } - } - - @Override - public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr, - @NonNull ContentObserver observer) { - mPeakRefreshRateObserver = observer; - } - - void notifyPeakRefreshRateChanged() { - if (mPeakRefreshRateObserver != null) { - mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/, - PEAK_REFRESH_RATE_URI); - } - } - - @Override - public boolean isDeviceInteractive(@NonNull Context context) { - return true; - } - } } diff --git a/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java b/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java index 112b2e98a7f1..f53894ad9ec5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java @@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.internal.util.Preconditions; -import com.android.server.testutils.FakeDeviceConfigInterface; +import com.android.server.wm.utils.FakeDeviceConfigInterface; import org.junit.After; import org.junit.Test; diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerConstantsTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerConstantsTest.java index 7a0ef0d7d7a9..52100116df53 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerConstantsTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerConstantsTest.java @@ -32,7 +32,7 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; -import com.android.server.testutils.FakeDeviceConfigInterface; +import com.android.server.wm.utils.FakeDeviceConfigInterface; import org.junit.After; import org.junit.Before; diff --git a/services/tests/servicestests/utils/com/android/server/testutils/FakeDeviceConfigInterface.java b/services/tests/wmtests/src/com/android/server/wm/utils/FakeDeviceConfigInterface.java index a67f64596ef5..2904a5b73646 100644 --- a/services/tests/servicestests/utils/com/android/server/testutils/FakeDeviceConfigInterface.java +++ b/services/tests/wmtests/src/com/android/server/wm/utils/FakeDeviceConfigInterface.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.testutils; +package com.android.server.wm.utils; import android.annotation.NonNull; import android.provider.DeviceConfig; @@ -22,7 +22,6 @@ import android.util.ArrayMap; import android.util.Pair; import com.android.internal.util.Preconditions; -import com.android.server.utils.DeviceConfigInterface; import java.lang.reflect.Constructor; import java.util.HashMap; @@ -123,19 +122,6 @@ public class FakeDeviceConfigInterface implements DeviceConfigInterface { } @Override - public float getFloat(String namespace, String name, float defaultValue) { - String value = getProperty(namespace, name); - if (value == null) { - return defaultValue; - } - try { - return Float.parseFloat(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - @Override public boolean getBoolean(String namespace, String name, boolean defaultValue) { String value = getProperty(namespace, name); return value != null ? Boolean.parseBoolean(value) : defaultValue; |