From 35d2ef154a27e51b0f1d7a0585dd601203278bdd Mon Sep 17 00:00:00 2001 From: Long Ling Date: Tue, 20 Aug 2019 15:01:14 -0700 Subject: DMD: Support 90hz only in the refresh rate zone Also allow DeviceConfig to change the zone behavior to 60 Hz only. Change BrightObserver priority to be the lowest so application request won't be overriden by BrightnessObserver Bug: 139487676 Change-Id: I959550350c1ea72f764984226350ebc6e7de591c (cherry picked from commit 73936631d57b4626ba0a389065e2dabcaf0daa79) --- .../android/hardware/display/DisplayManager.java | 23 +++- core/res/res/values/config.xml | 4 + core/res/res/values/symbols.xml | 1 + .../server/display/DisplayModeDirector.java | 128 ++++++++++++++++----- 4 files changed, 121 insertions(+), 35 deletions(-) diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 5d8fa92263c4..0b25dbd78611 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -829,23 +829,36 @@ public final class DisplayManager { public interface DeviceConfig { /** - * Key for accessing the 60 hz only regions. + * Key for refresh rate in the zone defined by thresholds. + * + * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER + * @see android.R.integer#config_defaultZoneBehavior + */ + String KEY_REFRESH_RATE_IN_ZONE = "refresh_rate_in_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_brightnessThresholdsOfPeakRefreshRate * @hide */ - String KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS = + String KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS = "peak_refresh_rate_brightness_thresholds"; /** - * Key for accessing the 60 hz only regions. + * 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_brightnessThresholdsOfPeakRefreshRate + * @see android.R.array#config_ambientThresholdsOfPeakRefreshRate * @hide */ - String KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS = "peak_refresh_rate_ambient_thresholds"; + String KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS = + "peak_refresh_rate_ambient_thresholds"; /** * Key for default peak refresh rate diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index df879816facb..1577a227ff67 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4167,6 +4167,10 @@ --> + + 0 + diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 92c5d2cf88df..0d9c4b39fea0 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3791,6 +3791,7 @@ + diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index 97fd02f53513..500a24282191 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -69,6 +69,7 @@ public class DisplayModeDirector { private static final int MSG_ALLOWED_MODES_CHANGED = 1; 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_ZONE_CHANGED = 4; // Special ID used to indicate that given vote is to be applied globally, rather than to a // specific display. @@ -440,23 +441,48 @@ public class DisplayModeDirector { mSettingsObserver.onDeviceConfigDefaultPeakRefreshRateChanged( defaultPeakRefreshRate); break; + + case MSG_REFRESH_RATE_IN_ZONE_CHANGED: + int refreshRateInZone = msg.arg1; + mBrightnessObserver.onDeviceConfigRefreshRateInZoneChanged( + refreshRateInZone); + break; } } } private static final class Vote { - // We split the app request into two priorities in case we can satisfy one desire without - // the other. - public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 0; - public static final int PRIORITY_APP_REQUEST_SIZE = 1; - public static final int PRIORITY_USER_SETTING_REFRESH_RATE = 2; - public static final int PRIORITY_LOW_BRIGHTNESS = 3; - public static final int PRIORITY_LOW_POWER_MODE = 4; + // 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 rate switch in certain conditions. + public static final int PRIORITY_LOW_BRIGHTNESS = 0; + + // SETTING_MIN_REFRESH_RATE is used to propose a lower bound of display refresh rate. + // It votes [MIN_REFRESH_RATE, Float.POSITIVE_INFINITY] + public static final int PRIORITY_USER_SETTING_MIN_REFRESH_RATE = 1; + + // We split the app request into different priorities in case we can satisfy one desire + // without the other. + + // Application can specify preferred refresh rate with below attrs. + // @see android.view.WindowManager.LayoutParams#preferredRefreshRate + // @see android.view.WindowManager.LayoutParams#preferredDisplayModeId + // System also forces some apps like blacklisted app to run at a lower refresh rate. + // @see android.R.array#config_highRefreshRateBlacklist + public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 2; + public static final int PRIORITY_APP_REQUEST_SIZE = 3; + + // SETTING_PEAK_REFRESH_RATE has a high priority and will restrict the bounds of the rest + // of low priority voters. It votes [0, max(PEAK, MIN)] + public static final int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 4; + + // LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on. + public static final int PRIORITY_LOW_POWER_MODE = 5; // Whenever a new priority is added, remember to update MIN_PRIORITY and/or MAX_PRIORITY as // appropriate, as well as priorityToString. - public static final int MIN_PRIORITY = PRIORITY_APP_REQUEST_REFRESH_RATE; + public static final int MIN_PRIORITY = PRIORITY_LOW_BRIGHTNESS; public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE; /** @@ -500,12 +526,16 @@ public class DisplayModeDirector { public static String priorityToString(int priority) { switch (priority) { + 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: return "PRIORITY_APP_REQUEST_REFRESH_RATE"; case PRIORITY_APP_REQUEST_SIZE: return "PRIORITY_APP_REQUEST_SIZE"; - case PRIORITY_USER_SETTING_REFRESH_RATE: - return "PRIORITY_USER_SETTING_REFRESH_RATE"; + case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE: + return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE"; case PRIORITY_LOW_POWER_MODE: return "PRIORITY_LOW_POWER_MODE"; default: @@ -608,12 +638,11 @@ public class DisplayModeDirector { float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(), Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate); - if (peakRefreshRate < minRefreshRate) { - peakRefreshRate = minRefreshRate; - } + updateVoteLocked(Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, + Vote.forRefreshRates(0f, Math.max(minRefreshRate, peakRefreshRate))); + updateVoteLocked(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, + Vote.forRefreshRates(minRefreshRate, Float.POSITIVE_INFINITY)); - Vote vote = Vote.forRefreshRates(minRefreshRate, peakRefreshRate); - updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote); mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, peakRefreshRate); } @@ -655,6 +684,7 @@ public class DisplayModeDirector { refreshRateVote = null; sizeVote = null; } + updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, refreshRateVote); updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote); return; @@ -799,6 +829,8 @@ public class DisplayModeDirector { private boolean mRefreshRateChangeable = false; private boolean mLowPowerModeEnabled = false; + private int mRefreshRateInZone; + BrightnessObserver(Context context, Handler handler) { super(handler); mContext = context; @@ -816,6 +848,7 @@ public class DisplayModeDirector { public void observe(SensorManager sensorManager) { mSensorManager = sensorManager; + // DeviceConfig is accessible after system ready. int[] brightnessThresholds = mDeviceConfigDisplaySettings.getBrightnessThresholds(); int[] ambientThresholds = mDeviceConfigDisplaySettings.getAmbientThresholds(); @@ -825,6 +858,8 @@ public class DisplayModeDirector { mDisplayBrightnessThresholds = brightnessThresholds; mAmbientBrightnessThresholds = ambientThresholds; } + + mRefreshRateInZone = mDeviceConfigDisplaySettings.getRefreshRateInZone(); restartObserver(); mDeviceConfigDisplaySettings.startListening(); } @@ -864,8 +899,16 @@ public class DisplayModeDirector { restartObserver(); } + public void onDeviceConfigRefreshRateInZoneChanged(int refreshRate) { + if (refreshRate != mRefreshRateInZone) { + mRefreshRateInZone = refreshRate; + restartObserver(); + } + } + public void dumpLocked(PrintWriter pw) { pw.println(" BrightnessObserver"); + pw.println(" mRefreshRateInZone: " + mRefreshRateInZone); for (int d: mDisplayBrightnessThresholds) { pw.println(" mDisplayBrightnessThreshold: " + d); @@ -952,6 +995,10 @@ public class DisplayModeDirector { * to value changes. */ private boolean checkShouldObserve(int[] a) { + if (mRefreshRateInZone <= 0) { + return false; + } + for (int d: a) { if (d >= 0) { return true; @@ -961,37 +1008,42 @@ public class DisplayModeDirector { return false; } - private void onBrightnessChangedLocked() { - int brightness = Settings.System.getInt(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, -1); - - Vote vote = null; + 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 && mAmbientLux <= ambi) { - vote = Vote.forRefreshRates(0f, 60f); + return true; } } else if (disp >= 0) { if (brightness <= disp) { - vote = Vote.forRefreshRates(0f, 60f); + return true; } } else if (ambi >= 0) { if (mAmbientLux <= ambi) { - vote = Vote.forRefreshRates(0f, 60f); + return true; } } + } - if (vote != null) { - break; - } + return false; + } + + private void onBrightnessChangedLocked() { + int brightness = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS, -1); + + Vote vote = null; + boolean insideZone = isInsideZone(brightness, mAmbientLux); + if (insideZone) { + vote = Vote.forRefreshRates(mRefreshRateInZone, mRefreshRateInZone); } if (DEBUG) { Slog.d(TAG, "Display brightness " + brightness + ", ambient lux " + mAmbientLux + - (vote != null ? " 60hz only" : " no refresh rate limit")); + ", Vote " + vote); } updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote); } @@ -1133,7 +1185,6 @@ public class DisplayModeDirector { } private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener { - public DeviceConfigDisplaySettings() { } @@ -1147,7 +1198,8 @@ public class DisplayModeDirector { */ public int[] getBrightnessThresholds() { return getIntArrayProperty( - DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS); + DisplayManager.DeviceConfig. + KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS); } /* @@ -1155,7 +1207,8 @@ public class DisplayModeDirector { */ public int[] getAmbientThresholds() { return getIntArrayProperty( - DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS); + DisplayManager.DeviceConfig. + KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS); } /* @@ -1172,17 +1225,32 @@ public class DisplayModeDirector { return defaultPeakRefreshRate; } + public int getRefreshRateInZone() { + int defaultRefreshRateInZone = mContext.getResources().getInteger( + R.integer.config_defaultRefreshRateInZone); + + int refreshRate = DeviceConfig.getInt( + DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_ZONE, + defaultRefreshRateInZone); + + return refreshRate; + } + @Override public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { int[] brightnessThresholds = getBrightnessThresholds(); int[] ambientThresholds = getAmbientThresholds(); Float defaultPeakRefreshRate = getDefaultPeakRefreshRate(); + int refreshRateInZone = getRefreshRateInZone(); mHandler.obtainMessage(MSG_BRIGHTNESS_THRESHOLDS_CHANGED, new Pair(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) { -- cgit v1.2.3 From b9412e0ee4716fa6bde5704e0165ad78562048ff Mon Sep 17 00:00:00 2001 From: Long Ling Date: Tue, 13 Aug 2019 16:07:14 -0700 Subject: [DO NOT MERGE] Check property name before apply high refresh rate black list Bug: 140233077 Change-Id: Ib2afc54c43ae5a9f3af8a0a0e65bc2c930428152 (cherry picked from commit 0113bc0c9520abcc5cdb7a985fc3402bf899252d) --- .../core/java/com/android/server/wm/HighRefreshRateBlacklist.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java b/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java index b33b68a7a5b2..271db2895eac 100644 --- a/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java +++ b/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java @@ -110,7 +110,9 @@ class HighRefreshRateBlacklist { private class OnPropertyChangedListener implements DeviceConfig.OnPropertyChangedListener { public void onPropertyChanged(@NonNull String namespace, @NonNull String name, @Nullable String value) { - updateBlacklist(value); + if (KEY_HIGH_REFRESH_RATE_BLACKLIST.equals(name)) { + updateBlacklist(value); + } } } } -- cgit v1.2.3 From ed7e4c9ecfb551d8f8a824d51e6efc3f66845dcc Mon Sep 17 00:00:00 2001 From: Jared Henderson Date: Wed, 21 Aug 2019 15:37:59 -0700 Subject: Update Xbox BT controller mapping for new FW The Xbox controller (product id 0x02fd) is going to have a new firmware update this fall that sends a different keycode (316/BUTTON_MODE) for the Xbox button. The goal is to enable the Xbox button to make it to apps on all Android versions -- with our without a controller-specific key mapping file. Unfortunately, the new Vendor_045e_Product_02fd.kl key mapping file that was added to Android Q maps the pre-firmware-update Xbox key code (172) to BUTTON_MODE, yet it makes no mention of key 316. This results in apps getting a raw 316 scan code instead of a BUTTON_MODE KeyEvent when using a controller with the latest firmware on Android Q. The fix is to add an additional key mapping for 316 that *also* maps to BUTTON_MODE. With both mappings in place, both pre and post firmware-updated controllers will get the correct behavior for the Xbox button on Android Q. Test: AFAIK, no CTS tests exist for Xbox controller key mappings; we'll need to add some at a later date. I was unable to test this change because I'm unable to write to the system directory on any of my devices, but I know that mapping 316 to BUTTON_MODE will fix the issue. Signed-off-by: Jared Henderson Bug: 139512030 Bug: 140808513 Merged-In: I8600ea79a0aa8557267d6ca712e5d56680e7a98b Change-Id: I8600ea79a0aa8557267d6ca712e5d56680e7a98b (cherry picked from commit b08c0be8a0e83404faa1a0424afe63ff490ddd37) --- data/keyboards/Vendor_045e_Product_02fd.kl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/data/keyboards/Vendor_045e_Product_02fd.kl b/data/keyboards/Vendor_045e_Product_02fd.kl index 512f7e134978..1b03497ae3d1 100644 --- a/data/keyboards/Vendor_045e_Product_02fd.kl +++ b/data/keyboards/Vendor_045e_Product_02fd.kl @@ -53,5 +53,10 @@ key 158 BUTTON_SELECT # Hamburger - 3 parallel lines key 315 BUTTON_START -# Xbox key +# There are at least two versions of firmware out for this controller. +# They send different linux keys for the "Xbox" button. +# Xbox key (original firmware) key 172 BUTTON_MODE + +# Xbox key (newer firmware) +key 316 BUTTON_MODE -- cgit v1.2.3 From 4ae8bc8f78a01bf0b62f1966f2f34937200efaa9 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Wed, 11 Sep 2019 22:03:01 +0100 Subject: Add keylayout for original xbox controller We are still missing a key layout for the original xbox controller with product id 02dd. Add the missing layout here. Bug: 140808513 Test: manual test by plugging in the actual joystick and using the custom tester app Change-Id: Ib84e3ac04ff58f890ce7743423cc9b869af347db (cherry picked from commit 0c1c820d9dcf66a86aaf393e97646082c522f543) --- data/keyboards/Vendor_045e_Product_02dd.kl | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 data/keyboards/Vendor_045e_Product_02dd.kl diff --git a/data/keyboards/Vendor_045e_Product_02dd.kl b/data/keyboards/Vendor_045e_Product_02dd.kl new file mode 100644 index 000000000000..3975cec24fcb --- /dev/null +++ b/data/keyboards/Vendor_045e_Product_02dd.kl @@ -0,0 +1,57 @@ +# Copyright (C) 2019 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. + +# +# XBox One Controller - Model 1697 - USB +# + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y + +key 310 BUTTON_L1 +key 311 BUTTON_R1 + +# Triggers. +axis 0x02 LTRIGGER +axis 0x05 RTRIGGER + +# Left and right stick. +# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd. +# This confuses applications that rely on the flat value because the joystick actually +# settles in a flat range of +/- 4096 or so. +axis 0x00 X flat 4096 +axis 0x01 Y flat 4096 +axis 0x03 Z flat 4096 +axis 0x04 RZ flat 4096 + +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +# Hat. +axis 0x10 HAT_X +axis 0x11 HAT_Y + + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Two overlapping rectangles +key 314 BUTTON_SELECT +# Hamburger - 3 parallel lines +key 315 BUTTON_START + +# Xbox key +key 316 BUTTON_MODE -- cgit v1.2.3 From 2e7f126b7cab5f5dda0ada5a5e61849f6094e228 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 7 Aug 2019 15:55:00 -0700 Subject: Assume sensors perform prox check Assume that doze sensors will be prox gated. Not doing so would be a bad idea anyway since the device would wake up way more often than it should and drain battery. Another improvement on this CL is that regular DozeSensors prox checks are trying to use a binned brightness sensor instead. Fixes: 138765669 Test: atest DozeSensorsTest DozeTriggersTest Test: single tap from AOD (observe no re-registration of lift) Test: 'reach' from AOD (observe no re-registration of lift) Test: receive notification with prox covered or unobstructed Change-Id: I1961ff9b16480ba1a60c397570494dd7acb4802d (cherry picked from commit f40bd8fbb65c896c824fe3f1a5be857bbe8ae281) Merged-In: I1961ff9b16480ba1a60c397570494dd7acb4802d (cherry picked from commit 9bab4a26245ecbc204b617cc3c046bdadf9e65e2) --- packages/SystemUI/res/values/config.xml | 3 -- .../src/com/android/systemui/doze/DozeSensors.java | 39 +++++----------------- .../com/android/systemui/doze/DozeTriggers.java | 20 ++++++----- .../systemui/statusbar/phone/DozeParameters.java | 4 --- .../systemui/doze/DozeConfigurationUtil.java | 1 - .../com/android/systemui/doze/DozeSensorsTest.java | 25 +++++--------- .../android/systemui/doze/DozeTriggersTest.java | 25 -------------- 7 files changed, 30 insertions(+), 87 deletions(-) diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 340cb3ad7358..6e8e8236a99a 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -196,9 +196,6 @@ 2000 - - false - diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 092eb46cad5e..026a62528c8d 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -107,8 +107,7 @@ public class DozeSensors { config.dozePickupSensorAvailable(), DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */, false /* touchscreen */, - false /* ignoresSetting */, - mDozeParameters.getPickupPerformsProxCheck()), + false /* ignoresSetting */), new TriggerSensor( findSensorWithType(config.doubleTapSensorType()), Settings.Secure.DOZE_DOUBLE_TAP_GESTURE, @@ -205,11 +204,8 @@ public class DozeSensors { public void updateListening() { boolean anyListening = false; for (TriggerSensor s : mSensors) { - // We don't want to be listening while we're PAUSED (prox sensor is covered) - // except when the sensor is already gated by prox. - boolean listen = mListening && (!mPaused || s.performsProxCheck()); - s.setListening(listen); - if (listen) { + s.setListening(mListening); + if (mListening) { anyListening = true; } } @@ -391,7 +387,6 @@ public class DozeSensors { private final boolean mReportsTouchCoordinates; private final boolean mSettingDefault; private final boolean mRequiresTouchscreen; - private final boolean mSensorPerformsProxCheck; protected boolean mRequested; protected boolean mRegistered; @@ -408,14 +403,12 @@ public class DozeSensors { boolean configured, int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen) { this(sensor, setting, settingDef, configured, pulseReason, reportsTouchCoordinates, - requiresTouchscreen, false /* ignoresSetting */, - false /* sensorPerformsProxCheck */); + requiresTouchscreen, false /* ignoresSetting */); } private TriggerSensor(Sensor sensor, String setting, boolean settingDef, boolean configured, int pulseReason, boolean reportsTouchCoordinates, - boolean requiresTouchscreen, boolean ignoresSetting, - boolean sensorPerformsProxCheck) { + boolean requiresTouchscreen, boolean ignoresSetting) { mSensor = sensor; mSetting = setting; mSettingDefault = settingDef; @@ -424,7 +417,6 @@ public class DozeSensors { mReportsTouchCoordinates = reportsTouchCoordinates; mRequiresTouchscreen = requiresTouchscreen; mIgnoresSetting = ignoresSetting; - mSensorPerformsProxCheck = sensorPerformsProxCheck; } public void setListening(boolean listen) { @@ -498,23 +490,13 @@ public class DozeSensors { screenX = event.values[0]; screenY = event.values[1]; } - mCallback.onSensorPulse(mPulseReason, mSensorPerformsProxCheck, screenX, screenY, - event.values); + mCallback.onSensorPulse(mPulseReason, screenX, screenY, event.values); if (!mRegistered) { updateListening(); // reregister, this sensor only fires once } })); } - /** - * If the sensor itself performs proximity checks, to avoid pocket dialing. - * Gated sensors don't need to be stopped when the {@link DozeMachine} is - * {@link DozeMachine.State#DOZE_AOD_PAUSED}. - */ - public boolean performsProxCheck() { - return mSensorPerformsProxCheck; - } - public void registerSettingsObserver(ContentObserver settingsObserver) { if (mConfigured && !TextUtils.isEmpty(mSetting)) { mResolver.registerContentObserver( @@ -610,8 +592,7 @@ public class DozeSensors { return; } if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event)); - mCallback.onSensorPulse(mPulseReason, true /* sensorPerformsProxCheck */, -1, -1, - event.getValues()); + mCallback.onSensorPulse(mPulseReason, -1, -1, event.getValues()); })); } } @@ -621,13 +602,11 @@ public class DozeSensors { /** * Called when a sensor requests a pulse * @param pulseReason Requesting sensor, e.g. {@link DozeLog#REASON_SENSOR_PICKUP} - * @param sensorPerformedProxCheck true if the sensor already checked for FAR proximity. * @param screenX the location on the screen where the sensor fired or -1 - * if the sensor doesn't support reporting screen locations. + * if the sensor doesn't support reporting screen locations. * @param screenY the location on the screen where the sensor fired or -1 * @param rawValues raw values array from the event. */ - void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck, - float screenX, float screenY, float[] rawValues); + void onSensorPulse(int pulseReason, float screenX, float screenY, float[] rawValues); } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 310f04abc36c..00bfb3f7cae8 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -41,6 +41,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.Preconditions; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.dock.DockManager; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.Assert; @@ -156,8 +157,7 @@ public class DozeTriggers implements DozeMachine.Part { } @VisibleForTesting - void onSensor(int pulseReason, boolean sensorPerformedProxCheck, - float screenX, float screenY, float[] rawValues) { + void onSensor(int pulseReason, float screenX, float screenY, float[] rawValues) { boolean isDoubleTap = pulseReason == DozeLog.REASON_SENSOR_DOUBLE_TAP; boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP; boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP; @@ -169,10 +169,11 @@ public class DozeTriggers implements DozeMachine.Part { if (isWakeDisplay) { onWakeScreen(wakeEvent, mMachine.isExecutingTransition() ? null : mMachine.getState()); } else if (isLongPress) { - requestPulse(pulseReason, sensorPerformedProxCheck, null /* onPulseSupressedListener */); + requestPulse(pulseReason, true /* alreadyPerformedProxCheck */, + null /* onPulseSupressedListener */); } else if (isWakeLockScreen) { if (wakeEvent) { - requestPulse(pulseReason, sensorPerformedProxCheck, + requestPulse(pulseReason, true /* alreadyPerformedProxCheck */, null /* onPulseSupressedListener */); } } else { @@ -191,8 +192,7 @@ public class DozeTriggers implements DozeMachine.Part { } else { mDozeHost.extendPulse(pulseReason); } - }, sensorPerformedProxCheck - || (mDockManager != null && mDockManager.isDocked()), pulseReason); + }, true /* alreadyPerformedProxCheck */, pulseReason); } if (isPickup) { @@ -278,7 +278,7 @@ public class DozeTriggers implements DozeMachine.Part { .setType(MetricsEvent.TYPE_OPEN) .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP)); } - }, false /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP); + }, true /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP); } else { boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); @@ -433,7 +433,11 @@ public class DozeTriggers implements DozeMachine.Part { public void check() { Preconditions.checkState(!mFinished && !mRegistered); - final Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + Sensor sensor = DozeSensors.findSensorWithType(mSensorManager, + mContext.getString(R.string.doze_brightness_sensor_type)); + if (sensor == null) { + sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + } if (sensor == null) { if (DozeMachine.DEBUG) Log.d(TAG, "ProxCheck: No sensor found"); finishWithResult(RESULT_UNKNOWN); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java index 10b48e71005d..bb6a38e1dcf5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -207,10 +207,6 @@ public class DozeParameters implements TunerService.Tunable, return SystemProperties.get(propName, mContext.getString(resId)); } - public boolean getPickupPerformsProxCheck() { - return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check); - } - public int getPulseVisibleDurationExtended() { return 2 * getPulseVisibleDuration(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java index 2ed0970ce44b..0c124fff53a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java @@ -37,7 +37,6 @@ public class DozeConfigurationUtil { when(params.getPulseOnSigMotion()).thenReturn(false); when(params.getPickupVibrationThreshold()).thenReturn(0); when(params.getProxCheckBeforePulse()).thenReturn(true); - when(params.getPickupPerformsProxCheck()).thenReturn(true); when(params.getPolicy()).thenReturn(mock(AlwaysOnDisplayPolicy.class)); when(params.doubleTapReportsTouchCoordinates()).thenReturn(false); when(params.getDisplayNeedsBlanking()).thenReturn(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java index 7df45a3d8949..cd6d1e069566 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java @@ -19,7 +19,6 @@ package com.android.systemui.doze; import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -79,8 +78,6 @@ public class DozeSensorsTest extends SysuiTestCase { private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy; @Mock private TriggerSensor mTriggerSensor; - @Mock - private TriggerSensor mProxGatedTriggerSensor; private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener; private TestableLooper mTestableLooper; private DozeSensors mDozeSensors; @@ -88,7 +85,6 @@ public class DozeSensorsTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - when(mProxGatedTriggerSensor.performsProxCheck()).thenReturn(true); mTestableLooper = TestableLooper.get(this); when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L); when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true); @@ -106,14 +102,14 @@ public class DozeSensorsTest extends SysuiTestCase { mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); mTestableLooper.processAllMessages(); verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), - anyBoolean(), anyFloat(), anyFloat(), eq(null)); + anyFloat(), anyFloat(), eq(null)); mDozeSensors.requestTemporaryDisable(); reset(mCallback); mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); mTestableLooper.processAllMessages(); verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), - anyBoolean(), anyFloat(), anyFloat(), eq(null)); + anyFloat(), anyFloat(), eq(null)); } @Test @@ -132,20 +128,17 @@ public class DozeSensorsTest extends SysuiTestCase { } @Test - public void testSetPaused_onlyPausesNonGatedSensors() { + public void testSetPaused_doesntPause_sensors() { mDozeSensors.setListening(true); verify(mTriggerSensor).setListening(eq(true)); - verify(mProxGatedTriggerSensor).setListening(eq(true)); - clearInvocations(mTriggerSensor, mProxGatedTriggerSensor); + clearInvocations(mTriggerSensor); mDozeSensors.setPaused(true); - verify(mTriggerSensor).setListening(eq(false)); - verify(mProxGatedTriggerSensor).setListening(eq(true)); - - clearInvocations(mTriggerSensor, mProxGatedTriggerSensor); - mDozeSensors.setPaused(false); verify(mTriggerSensor).setListening(eq(true)); - verify(mProxGatedTriggerSensor).setListening(eq(true)); + + clearInvocations(mTriggerSensor); + mDozeSensors.setListening(false); + verify(mTriggerSensor).setListening(eq(false)); } private class TestableDozeSensors extends DozeSensors { @@ -161,7 +154,7 @@ public class DozeSensorsTest extends SysuiTestCase { mWakeLockScreenListener = (PluginSensor) sensor; } } - mSensors = new TriggerSensor[] {mTriggerSensor, mProxGatedTriggerSensor}; + mSensors = new TriggerSensor[] {mTriggerSensor}; } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java index d4642238d8fd..e190f9923da8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java @@ -20,7 +20,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -134,28 +133,4 @@ public class DozeTriggersTest extends SysuiTestCase { mTriggers.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH); verify(mDockManagerFake).removeListener(any()); } - - @Test - public void testOnSensor_whenUndockedWithNearAndDoubleTapScreen_shouldNotWakeUp() { - mSensors.getMockProximitySensor().sendProximityResult(false /* far */); - - mTriggers.onSensor(DozeLog.REASON_SENSOR_DOUBLE_TAP, - false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */, - null /* rawValues */); - verify(mMachine, never()).wakeUp(); - } - - @Test - public void testOnSensor_whenDockedWithNearAndDoubleTapScreen_shouldWakeUp() { - doReturn(true).when(mDockManagerFake).isDocked(); - doReturn(true).when(mParameters).getDisplayNeedsBlanking(); - mSensors.getMockProximitySensor().sendProximityResult(false /* far */); - - mTriggers.onSensor(DozeLog.REASON_SENSOR_DOUBLE_TAP, - false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */, - null /* rawValues */); - - verify(mHost).setAodDimmingScrim(eq(1f)); - verify(mMachine).wakeUp(); - } } -- cgit v1.2.3 From 3fb49ee6a72dd4e374ac048d2ca62494074c2088 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Mon, 9 Sep 2019 14:06:55 -0700 Subject: Fix issue where notif wouldn't HUN DozeSensors and DozeTriggers have code that perform proximity checks in slightly different ways. DozeSensors was updated as part of ag/9185335 bug DozeTriggers wasn't. Bug: 9185335 Fixes: 140701062 Bug: 138765669 Test: partially cover prox, send notification, look at screen Change-Id: Ic85181abb3edd4c77c427faefa4cd6b9c35b498f Merged-In: Ic85181abb3edd4c77c427faefa4cd6b9c35b498f (cherry picked from commit 19ef3004c16f7fa572b98a5c3755fedcfc407410) --- .../src/com/android/systemui/doze/DozeTriggers.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 00bfb3f7cae8..bab64db4519c 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -417,6 +417,9 @@ public class DozeTriggers implements DozeMachine.Part { mDozeSensors.dump(pw); } + /** + * @see DozeSensors.ProxSensor + */ private abstract class ProximityCheck implements SensorEventListener, Runnable { private static final int TIMEOUT_DELAY_MS = 500; @@ -428,6 +431,7 @@ public class DozeTriggers implements DozeMachine.Part { private boolean mRegistered; private boolean mFinished; private float mMaxRange; + private boolean mUsingBrightnessSensor; protected abstract void onProximityResult(int result); @@ -435,6 +439,7 @@ public class DozeTriggers implements DozeMachine.Part { Preconditions.checkState(!mFinished && !mRegistered); Sensor sensor = DozeSensors.findSensorWithType(mSensorManager, mContext.getString(R.string.doze_brightness_sensor_type)); + mUsingBrightnessSensor = sensor != null; if (sensor == null) { sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); } @@ -453,6 +458,9 @@ public class DozeTriggers implements DozeMachine.Part { mRegistered = true; } + /** + * @see DozeSensors.ProxSensor#onSensorChanged(SensorEvent) + */ @Override public void onSensorChanged(SensorEvent event) { if (event.values.length == 0) { @@ -462,7 +470,14 @@ public class DozeTriggers implements DozeMachine.Part { if (DozeMachine.DEBUG) { Log.d(TAG, "ProxCheck: Event: value=" + event.values[0] + " max=" + mMaxRange); } - final boolean isNear = event.values[0] < mMaxRange; + final boolean isNear; + if (mUsingBrightnessSensor) { + // The custom brightness sensor is gated by the proximity sensor and will + // return 0 whenever prox is covered. + isNear = event.values[0] == 0; + } else { + isNear = event.values[0] < mMaxRange; + } finishWithResult(isNear ? RESULT_NEAR : RESULT_FAR); } } -- cgit v1.2.3