Merge "[Autofill PCC] Restrict complete logging to debug bulids" into udc-dev am: d4460ca5cc am: 1f664c79dd
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23156537
Change-Id: Ife8eed1aafcc5c64dac79d179b038e5720c92449
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 411d157..4851279 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -694,12 +694,22 @@
*/
@Override
public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
- if ((keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE)
- && event.isTracking()
- && !event.isCanceled()
- && !WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
- onBackPressed();
- return true;
+ if (event.isTracking() && !event.isCanceled()) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ if (!WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
+ onBackPressed();
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_ESCAPE:
+ if (mCancelable) {
+ cancel();
+ } else {
+ dismiss();
+ }
+ return true;
+ }
}
return false;
}
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index c87911e..244523f 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -441,7 +441,7 @@
<string name="permdesc_writeSettings" msgid="8293047411196067188">"Колдонмого системанын коопсуздук параметрлеринин дайындарын өзгөртүү мүмкүнчүлүгүн берет. Кесепттүү колдонмолор системаңыздын конфигурациясын бузуп салышы мүмкүн."</string>
<string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"түзмөктү жандырганда иштеп баштоо"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Колдонмого тутум жүктөлүп бүтөөрү менен өзүн-өзү иштетүү мүмкүнчүлүгүн берет. Бул планшеттин ишке киргизилишин кыйла создуктуруп, планшеттин үзгүлтүксүз иштешин жайлатып салышы мүмкүн."</string>
- <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Тутум күйгүзүлөрү менен колдонмого өз алдынча иштеп баштоого уруксат берет. Ага байланыштуу Android TV түзмөгүңүз кечирээк күйгүзүлүп, ошондой эле колдонмо такай иштеп тургандыктан, түзмөк жайыраак иштеп калышы мүмкүн."</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Система күйгүзүлөрү менен колдонмого өз алдынча иштеп баштоого уруксат берет. Ага байланыштуу Android TV түзмөгүңүз кечирээк күйгүзүлүп, ошондой эле колдонмо такай иштеп тургандыктан, түзмөк жайыраак иштеп калышы мүмкүн."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Колдонмого тутум жүктөлүп бүтөөрү менен өзүн-өзү иштетүү мүмкүнчүлүгүн берет. Бул телефондун ишке киргизилишин кыйла создуктуруп, телефондун үзгүлтүксүз иштешин жайлатып салышы мүмкүн."</string>
<string name="permlab_broadcastSticky" msgid="4552241916400572230">"жабышчаак таркатманы жөнөтүү"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Колдонмого берүү токтогондон кийин улантыла берүүчү жабышкак берүүлөрдү жөнөтүү уруксатын берет. Муну ашыкча колдонуу, эстутумду өтө көп пайдаланууга алып келип, планшеттин жай же туруксуз иштөөсүнүнө себепкер болушу мүмкүн."</string>
@@ -1207,7 +1207,7 @@
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Сүрөткө тартуу"</string>
<string name="alwaysUse" msgid="3153558199076112903">"Бул аракет үчүн демейки боюнча колдонулсун."</string>
<string name="use_a_different_app" msgid="4987790276170972776">"Башка колдонмону пайдалануу"</string>
- <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Тутум жөндөөлөрүндөгү демейкини тазалоо > Колдонмолор > Жүктөлүп алынды."</string>
+ <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Система жөндөөлөрүндөгү демейкини тазалоо > Колдонмолор > Жүктөлүп алынды."</string>
<string name="chooseActivity" msgid="8563390197659779956">"Аракет тандаңыз"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"USB түзмөгү үчүн колдонмо тандаңыз"</string>
<string name="noApplications" msgid="1186909265235544019">"Бул аракетти аткара турган колдонмо жок."</string>
@@ -1623,7 +1623,7 @@
<string name="default_audio_route_name_external_device" msgid="8124229858618975">"Тышкы түзмөк"</string>
<string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Кулакчын"</string>
<string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
- <string name="default_audio_route_category_name" msgid="5241740395748134483">"Тутум"</string>
+ <string name="default_audio_route_category_name" msgid="5241740395748134483">"Система"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Bluetooth аудио"</string>
<string name="wireless_display_route_description" msgid="8297563323032966831">"Зымсыз дисплей"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"Тышкы экранга чыгаруу"</string>
@@ -2068,7 +2068,7 @@
<string name="screenshot_edit" msgid="7408934887203689207">"Түзөтүү"</string>
<string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Чалуулар менен билдирмелер дирилдөө режиминде иштейт"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Чалуулар менен эскертмелердин үнү өчүрүлөт"</string>
- <string name="notification_channel_system_changes" msgid="2462010596920209678">"Тутум өзгөрүүлөрү"</string>
+ <string name="notification_channel_system_changes" msgid="2462010596920209678">"Система өзгөрүүлөрү"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Тынчымды алба"</string>
<string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Жаңы: \"Тынчымды алба\" режими билдирмелерди жашырууда"</string>
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Көбүрөөк маалымат алып, өзгөртүү үчүн таптаңыз."</string>
@@ -2078,7 +2078,7 @@
<string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 версиясынан баштап билдирмелерди жөнөтүү үчүн орноткон колдонмолоруңузга уруксат берүү керек. Учурдагы колдонмолор үчүн бул уруксатты өзгөртүү үчүн таптап коюңуз."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Кийинчерээк эскертүү"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Жабуу"</string>
- <string name="notification_app_name_system" msgid="3045196791746735601">"Тутум"</string>
+ <string name="notification_app_name_system" msgid="3045196791746735601">"Система"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Параметрлер"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Камера"</string>
<string name="notification_appops_microphone_active" msgid="581333393214739332">"Микрофон"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 903ee0b..aad9eb2 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -694,7 +694,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"आफ्नो फोनमा अझ सीधा हेर्नुहोस्"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"आफ्नो फोनमा अझ सीधा हेर्नुहोस्"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"आफ्नो फोनमा अझ सीधा हेर्नुहोस्"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"तपाईंको अनुहार लुकाउने सबै कुरा हटाउनुहोस्।"</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"आफ्नो अनुहार छोप्ने सबै कुरा हटाउनुहोस्।"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"कालो रङको पट्टीलगायत आफ्नो स्क्रिनको माथिल्लो भाग सफा गर्नुहोस्"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 6f5b3ff..d327499 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"ສຽງ HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"ສຽງ HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ອຸປະກອນຊ່ວຍຟັງ"</string>
- <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="6125267378720026515">"ສຽງ LE (ການທົດລອງ)"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ເຊື່ອມຕໍ່ຫາອຸປະກອນຊ່ວຍຟັງແລ້ວ"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"ເຊື່ອມຕໍ່ຫາສຽງ LE ແລ້ວ"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ເຊື່ອມຕໍ່ກັບສື່ດ້ານສຽງແລ້ວ"</string>
diff --git a/packages/SystemUI/res-product/values-my/strings.xml b/packages/SystemUI/res-product/values-my/strings.xml
index 68711e8..4ec1ff6 100644
--- a/packages/SystemUI/res-product/values-my/strings.xml
+++ b/packages/SystemUI/res-product/values-my/strings.xml
@@ -23,7 +23,7 @@
<string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"ကြိုးမဲ့အားသွင်းရန် ဖုန်းကို ပြန်၍ချိန်ပါ"</string>
<string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android TV စက်သည် မကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားရန် ခလုတ်တစ်ခုကို နှိပ်ပါ။"</string>
<string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"စက်သည် မကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားရန် နှိပ်ပါ။"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="408124574073032188">"တက်ဘလက်တွင် ဆင်းမ်ကတ်မရှိပါ။"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="408124574073032188">"တက်ဘလက်တွင် ဆင်းမ်မရှိပါ။"</string>
<string name="keyguard_missing_sim_message" product="default" msgid="2605468359948247208">"ဖုန်းတွင် ဆင်းမ်မရှိပါ။"</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"ပင်နံပါတ် ကိုက်ညီမှု မရှိပါ"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"တက်ဘလက်ကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းခဲ့လျှင် ဤတက်ဘလက်ကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 93b6cda..4118b6b 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -985,8 +985,10 @@
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Luidsprekers en skerms"</string>
<string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Voorgestelde toestelle"</string>
- <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Stop jou gedeelde sessie om media na ’n ander toestel toe te skuif"</string>
- <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Stop"</string>
+ <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
+ <skip />
+ <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
+ <skip />
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitsaai werk"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Saai uit"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mense in jou omtrek met versoenbare Bluetooth-toestelle kan na die media luister wat jy uitsaai"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 7b4e12d..c7ecb62 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -1009,8 +1009,10 @@
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Bozgorailuak eta pantailak"</string>
<string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Iradokitako gailuak"</string>
- <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Gelditu partekatutako saioa multimedia-edukia beste gailu batera eramateko"</string>
- <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Gelditu"</string>
+ <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
+ <skip />
+ <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
+ <skip />
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Nola funtzionatzen dute iragarpenek?"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Iragarri"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth bidezko gailu bateragarriak dituzten inguruko pertsonek iragartzen ari zaren multimedia-edukia entzun dezakete"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 4b6fd34..32a6481 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -691,8 +691,7 @@
// TODO(b/259428678): Tracking Bug
@JvmField
- val KEYBOARD_BACKLIGHT_INDICATOR =
- unreleasedFlag(2601, "keyboard_backlight_indicator", teamfood = true)
+ val KEYBOARD_BACKLIGHT_INDICATOR = releasedFlag(2601, "keyboard_backlight_indicator")
// TODO(b/277192623): Tracking Bug
@JvmField
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 42de7f0..fcae081 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -38,6 +38,7 @@
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.input.InputManager;
+import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -192,6 +193,7 @@
private final ViewConfiguration mViewConfiguration;
private final WindowManager mWindowManager;
private final IWindowManager mWindowManagerService;
+ private final InputManager mInputManager;
private final Optional<Pip> mPipOptional;
private final Optional<DesktopMode> mDesktopModeOptional;
private final FalsingManager mFalsingManager;
@@ -203,6 +205,7 @@
private final int mDisplayId;
private final Executor mMainExecutor;
+ private final Handler mMainHandler;
private final Executor mBackgroundExecutor;
private final Rect mPipExcludedBounds = new Rect();
@@ -246,6 +249,8 @@
private boolean mIsAttached;
private boolean mIsGesturalModeEnabled;
+ private boolean mIsTrackpadConnected;
+ private boolean mUsingThreeButtonNav;
private boolean mIsEnabled;
private boolean mIsNavBarShownTransiently;
private boolean mIsBackGestureAllowed;
@@ -343,12 +348,48 @@
}
};
+ private final InputManager.InputDeviceListener mInputDeviceListener =
+ new InputManager.InputDeviceListener() {
+
+ // Only one trackpad can be connected to a device at a time, since it takes over the
+ // only USB port.
+ private int mTrackpadDeviceId;
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ if (isTrackpadDevice(deviceId)) {
+ mTrackpadDeviceId = deviceId;
+ update(true /* isTrackpadConnected */);
+ }
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) { }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ if (mTrackpadDeviceId == deviceId) {
+ update(false /* isTrackpadConnected */);
+ }
+ }
+
+ private void update(boolean isTrackpadConnected) {
+ boolean isPreviouslyTrackpadConnected = mIsTrackpadConnected;
+ mIsTrackpadConnected = isTrackpadConnected;
+ if (isPreviouslyTrackpadConnected != mIsTrackpadConnected) {
+ updateIsEnabled();
+ updateCurrentUserResources();
+ }
+ }
+ };
+
EdgeBackGestureHandler(
Context context,
OverviewProxyService overviewProxyService,
SysUiState sysUiState,
PluginManager pluginManager,
@Main Executor executor,
+ @Main Handler handler,
@Background Executor backgroundExecutor,
UserTracker userTracker,
ProtoTracer protoTracer,
@@ -357,6 +398,7 @@
ViewConfiguration viewConfiguration,
WindowManager windowManager,
IWindowManager windowManagerService,
+ InputManager inputManager,
Optional<Pip> pipOptional,
Optional<DesktopMode> desktopModeOptional,
FalsingManager falsingManager,
@@ -367,6 +409,7 @@
mContext = context;
mDisplayId = context.getDisplayId();
mMainExecutor = executor;
+ mMainHandler = handler;
mBackgroundExecutor = backgroundExecutor;
mUserTracker = userTracker;
mOverviewProxyService = overviewProxyService;
@@ -378,6 +421,7 @@
mViewConfiguration = viewConfiguration;
mWindowManager = windowManager;
mWindowManagerService = windowManagerService;
+ mInputManager = inputManager;
mPipOptional = pipOptional;
mDesktopModeOptional = desktopModeOptional;
mFalsingManager = falsingManager;
@@ -386,6 +430,8 @@
mFeatureFlags = featureFlags;
mLightBarControllerProvider = lightBarControllerProvider;
mLastReportedConfig.setTo(mContext.getResources().getConfiguration());
+ mIsTrackpadGestureFeaturesEnabled = mFeatureFlags.isEnabled(
+ Flags.TRACKPAD_GESTURE_FEATURES);
ComponentName recentsComponentName = ComponentName.unflattenFromString(
context.getString(com.android.internal.R.string.config_recentsComponentName));
if (recentsComponentName != null) {
@@ -417,7 +463,7 @@
ViewConfiguration.getLongPressTimeout());
mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(
- mContext.getMainThreadHandler(), mContext, this::onNavigationSettingsChanged);
+ mMainHandler, mContext, this::onNavigationSettingsChanged);
updateCurrentUserResources();
}
@@ -496,6 +542,15 @@
mProtoTracer.add(this);
mOverviewProxyService.addCallback(mQuickSwitchListener);
mSysUiState.addCallback(mSysUiStateCallback);
+ if (mIsTrackpadGestureFeaturesEnabled) {
+ mInputManager.registerInputDeviceListener(mInputDeviceListener, mMainHandler);
+ int [] inputDevices = mInputManager.getInputDeviceIds();
+ for (int inputDeviceId : inputDevices) {
+ if (isTrackpadDevice(inputDeviceId)) {
+ mIsTrackpadConnected = true;
+ }
+ }
+ }
updateIsEnabled();
mUserTracker.addCallback(mUserChangedCallback, mMainExecutor);
}
@@ -508,6 +563,7 @@
mProtoTracer.remove(this);
mOverviewProxyService.removeCallback(mQuickSwitchListener);
mSysUiState.removeCallback(mSysUiStateCallback);
+ mInputManager.unregisterInputDeviceListener(mInputDeviceListener);
updateIsEnabled();
mUserTracker.removeCallback(mUserChangedCallback);
}
@@ -516,7 +572,9 @@
* @see NavigationModeController.ModeChangedListener#onNavigationModeChanged
*/
public void onNavigationModeChanged(int mode) {
- mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mode);
+ mUsingThreeButtonNav = QuickStepContract.isLegacyMode(mode);
+ mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mode) || (
+ mIsTrackpadGestureFeaturesEnabled && mUsingThreeButtonNav && mIsTrackpadConnected);
updateIsEnabled();
updateCurrentUserResources();
}
@@ -606,8 +664,6 @@
// Add a nav bar panel window
mIsNewBackAffordanceEnabled = mFeatureFlags.isEnabled(Flags.NEW_BACK_AFFORDANCE);
- mIsTrackpadGestureFeaturesEnabled = mFeatureFlags.isEnabled(
- Flags.TRACKPAD_GESTURE_FEATURES);
resetEdgeBackPlugin();
mPluginManager.addPluginListener(
this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false);
@@ -811,6 +867,12 @@
mDisplaySize.y - insets.bottom);
}
+ private boolean isTrackpadDevice(int deviceId) {
+ InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
+ return inputDevice.getSources() == (InputDevice.SOURCE_MOUSE
+ | InputDevice.SOURCE_TOUCHPAD);
+ }
+
private boolean desktopExcludeRegionContains(int x, int y) {
return mDesktopModeExcludeRegion.contains(x, y);
}
@@ -935,17 +997,20 @@
mMLResults = 0;
mLogGesture = false;
mInRejectedExclusion = false;
- // Trackpad back gestures don't have zones, so we don't need to check if the down event
- // is within insets. Also we don't allow back for button press from the trackpad, and
- // yet we do with a mouse.
boolean isWithinInsets = isWithinInsets((int) ev.getX(), (int) ev.getY());
- mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed
- && !isButtonPressFromTrackpad(ev)
- && (isTrackpadMultiFingerSwipe || isWithinInsets)
+ boolean isBackAllowedCommon = !mDisabledForQuickstep && mIsBackGestureAllowed
&& !mGestureBlockingActivityRunning
- && !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
- && (isValidTrackpadBackGesture(isTrackpadMultiFingerSwipe)
- || isWithinTouchRegion((int) ev.getX(), (int) ev.getY()));
+ && !QuickStepContract.isBackGestureDisabled(mSysUiFlags);
+ if (isTrackpadMultiFingerSwipe) {
+ // Trackpad back gestures don't have zones, so we don't need to check if the down
+ // event is within insets.
+ mAllowGesture = isBackAllowedCommon && isValidTrackpadBackGesture(
+ isTrackpadMultiFingerSwipe);
+ } else {
+ mAllowGesture = isBackAllowedCommon && !mUsingThreeButtonNav && isWithinInsets
+ && isWithinTouchRegion((int) ev.getX(), (int) ev.getY())
+ && !isButtonPressFromTrackpad(ev);
+ }
if (mAllowGesture) {
mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
mEdgeBackPlugin.onMotionEvent(ev);
@@ -1048,6 +1113,7 @@
}
private boolean isButtonPressFromTrackpad(MotionEvent ev) {
+ // We don't allow back for button press from the trackpad, and yet we do with a mouse.
int sources = InputManager.getInstance().getInputDevice(ev.getDeviceId()).getSources();
return (sources & (SOURCE_MOUSE | SOURCE_TOUCHPAD)) == sources && ev.getButtonState() != 0;
}
@@ -1170,6 +1236,8 @@
pw.println(" mPredictionLog=" + String.join("\n", mPredictionLog));
pw.println(" mGestureLogInsideInsets=" + String.join("\n", mGestureLogInsideInsets));
pw.println(" mGestureLogOutsideInsets=" + String.join("\n", mGestureLogOutsideInsets));
+ pw.println(" mIsTrackpadConnected=" + mIsTrackpadConnected);
+ pw.println(" mUsingThreeButtonNav=" + mUsingThreeButtonNav);
pw.println(" mEdgeBackPlugin=" + mEdgeBackPlugin);
if (mEdgeBackPlugin != null) {
mEdgeBackPlugin.dump(pw);
@@ -1219,6 +1287,7 @@
private final SysUiState mSysUiState;
private final PluginManager mPluginManager;
private final Executor mExecutor;
+ private final Handler mHandler;
private final Executor mBackgroundExecutor;
private final UserTracker mUserTracker;
private final ProtoTracer mProtoTracer;
@@ -1227,6 +1296,7 @@
private final ViewConfiguration mViewConfiguration;
private final WindowManager mWindowManager;
private final IWindowManager mWindowManagerService;
+ private final InputManager mInputManager;
private final Optional<Pip> mPipOptional;
private final Optional<DesktopMode> mDesktopModeOptional;
private final FalsingManager mFalsingManager;
@@ -1241,6 +1311,7 @@
SysUiState sysUiState,
PluginManager pluginManager,
@Main Executor executor,
+ @Main Handler handler,
@Background Executor backgroundExecutor,
UserTracker userTracker,
ProtoTracer protoTracer,
@@ -1249,6 +1320,7 @@
ViewConfiguration viewConfiguration,
WindowManager windowManager,
IWindowManager windowManagerService,
+ InputManager inputManager,
Optional<Pip> pipOptional,
Optional<DesktopMode> desktopModeOptional,
FalsingManager falsingManager,
@@ -1261,6 +1333,7 @@
mSysUiState = sysUiState;
mPluginManager = pluginManager;
mExecutor = executor;
+ mHandler = handler;
mBackgroundExecutor = backgroundExecutor;
mUserTracker = userTracker;
mProtoTracer = protoTracer;
@@ -1269,6 +1342,7 @@
mViewConfiguration = viewConfiguration;
mWindowManager = windowManager;
mWindowManagerService = windowManagerService;
+ mInputManager = inputManager;
mPipOptional = pipOptional;
mDesktopModeOptional = desktopModeOptional;
mFalsingManager = falsingManager;
@@ -1286,6 +1360,7 @@
mSysUiState,
mPluginManager,
mExecutor,
+ mHandler,
mBackgroundExecutor,
mUserTracker,
mProtoTracer,
@@ -1294,6 +1369,7 @@
mViewConfiguration,
mWindowManager,
mWindowManagerService,
+ mInputManager,
mPipOptional,
mDesktopModeOptional,
mFalsingManager,
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index 27215b2..b0c1d05 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -44,7 +44,7 @@
private static final String TAG = "DynamicSystemService";
private static final long MINIMUM_SD_MB = (30L << 10);
private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
- private static final String PATH_DEFAULT = "/data/gsi/";
+ private static final String PATH_DEFAULT = "/data/gsi/dsu/";
private Context mContext;
private String mInstallPath, mDsuSlot;
private volatile IGsiService mGsiService;
diff --git a/services/core/java/com/android/server/input/InputFeatureFlagProvider.java b/services/core/java/com/android/server/input/InputFeatureFlagProvider.java
new file mode 100644
index 0000000..3854ada
--- /dev/null
+++ b/services/core/java/com/android/server/input/InputFeatureFlagProvider.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input;
+
+import android.sysprop.InputProperties;
+
+import java.util.Optional;
+
+/**
+ * A component of {@link InputManagerService} responsible for managing the input sysprop flags
+ *
+ * @hide
+ */
+@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+public final class InputFeatureFlagProvider {
+
+ // To disable Keyboard backlight control via Framework, run:
+ // 'adb shell setprop persist.input.keyboard_backlight_control.enabled false' (requires restart)
+ private static final boolean KEYBOARD_BACKLIGHT_CONTROL_ENABLED =
+ InputProperties.enable_keyboard_backlight_control().orElse(true);
+
+ // To disable Framework controlled keyboard backlight animation run:
+ // adb shell setprop persist.input.keyboard.backlight_animation.enabled false (requires restart)
+ private static final boolean KEYBOARD_BACKLIGHT_ANIMATION_ENABLED =
+ InputProperties.enable_keyboard_backlight_animation().orElse(false);
+
+ private static Optional<Boolean> sKeyboardBacklightControlOverride = Optional.empty();
+ private static Optional<Boolean> sKeyboardBacklightAnimationOverride = Optional.empty();
+
+ public static boolean isKeyboardBacklightControlEnabled() {
+ return sKeyboardBacklightControlOverride.orElse(KEYBOARD_BACKLIGHT_CONTROL_ENABLED);
+ }
+
+ public static boolean isKeyboardBacklightAnimationEnabled() {
+ return sKeyboardBacklightAnimationOverride.orElse(KEYBOARD_BACKLIGHT_ANIMATION_ENABLED);
+ }
+
+ public static void setKeyboardBacklightControlEnabled(boolean enabled) {
+ sKeyboardBacklightControlOverride = Optional.of(enabled);
+ }
+
+ public static void setKeyboardBacklightAnimationEnabled(boolean enabled) {
+ sKeyboardBacklightAnimationOverride = Optional.of(enabled);
+ }
+
+ /**
+ * Clears all input feature flag overrides.
+ */
+ public static void clearOverrides() {
+ sKeyboardBacklightControlOverride = Optional.empty();
+ sKeyboardBacklightAnimationOverride = Optional.empty();
+ }
+}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 662591e..9f3ab88 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -74,7 +74,6 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.VibrationEffect;
import android.os.vibrator.StepSegment;
@@ -160,11 +159,6 @@
private static final AdditionalDisplayInputProperties
DEFAULT_ADDITIONAL_DISPLAY_INPUT_PROPERTIES = new AdditionalDisplayInputProperties();
- // To disable Keyboard backlight control via Framework, run:
- // 'adb shell setprop persist.input.keyboard_backlight_control.enabled false' (requires restart)
- private static final boolean KEYBOARD_BACKLIGHT_CONTROL_ENABLED = SystemProperties.getBoolean(
- "persist.input.keyboard.backlight_control.enabled", true);
-
private final NativeInputManagerService mNative;
private final Context mContext;
@@ -439,10 +433,9 @@
mKeyboardLayoutManager = new KeyboardLayoutManager(mContext, mNative, mDataStore,
injector.getLooper());
mBatteryController = new BatteryController(mContext, mNative, injector.getLooper());
- mKeyboardBacklightController =
- KEYBOARD_BACKLIGHT_CONTROL_ENABLED ? new KeyboardBacklightController(mContext,
- mNative, mDataStore, injector.getLooper())
- : new KeyboardBacklightControllerInterface() {};
+ mKeyboardBacklightController = InputFeatureFlagProvider.isKeyboardBacklightControlEnabled()
+ ? new KeyboardBacklightController(mContext, mNative, mDataStore,
+ injector.getLooper()) : new KeyboardBacklightControllerInterface() {};
mKeyRemapper = new KeyRemapper(mContext, mNative, mDataStore, injector.getLooper());
mUseDevInputEventForAudioJack =
diff --git a/services/core/java/com/android/server/input/KeyboardBacklightController.java b/services/core/java/com/android/server/input/KeyboardBacklightController.java
index 48c346a..61ca0cb 100644
--- a/services/core/java/com/android/server/input/KeyboardBacklightController.java
+++ b/services/core/java/com/android/server/input/KeyboardBacklightController.java
@@ -16,6 +16,7 @@
package com.android.server.input;
+import android.animation.ValueAnimator;
import android.annotation.BinderThread;
import android.content.Context;
import android.graphics.Color;
@@ -70,6 +71,8 @@
private static final int MSG_INTERACTIVE_STATE_CHANGED = 6;
private static final int MAX_BRIGHTNESS = 255;
private static final int NUM_BRIGHTNESS_CHANGE_STEPS = 10;
+ private static final long TRANSITION_ANIMATION_DURATION_MILLIS =
+ Duration.ofSeconds(1).toMillis();
private static final String UEVENT_KEYBOARD_BACKLIGHT_TAG = "kbd_backlight";
@@ -85,6 +88,7 @@
@GuardedBy("mDataStore")
private final PersistentDataStore mDataStore;
private final Handler mHandler;
+ private final AnimatorFactory mAnimatorFactory;
// Always access on handler thread or need to lock this for synchronization.
private final SparseArray<KeyboardBacklightState> mKeyboardBacklights = new SparseArray<>(1);
// Maintains state if all backlights should be on or turned off
@@ -109,10 +113,17 @@
KeyboardBacklightController(Context context, NativeInputManagerService nativeService,
PersistentDataStore dataStore, Looper looper) {
+ this(context, nativeService, dataStore, looper, ValueAnimator::ofInt);
+ }
+
+ @VisibleForTesting
+ KeyboardBacklightController(Context context, NativeInputManagerService nativeService,
+ PersistentDataStore dataStore, Looper looper, AnimatorFactory animatorFactory) {
mContext = context;
mNative = nativeService;
mDataStore = dataStore;
mHandler = new Handler(looper, this::handleMessage);
+ mAnimatorFactory = animatorFactory;
}
@Override
@@ -177,8 +188,7 @@
} else {
newBrightnessLevel = Math.max(currBrightnessLevel - 1, 0);
}
- updateBacklightState(deviceId, keyboardBacklight, newBrightnessLevel,
- true /* isTriggeredByKeyPress */);
+ updateBacklightState(deviceId, newBrightnessLevel, true /* isTriggeredByKeyPress */);
synchronized (mDataStore) {
try {
@@ -203,8 +213,7 @@
if (index < 0) {
index = Math.min(NUM_BRIGHTNESS_CHANGE_STEPS, -(index + 1));
}
- updateBacklightState(inputDevice.getId(), keyboardBacklight, index,
- false /* isTriggeredByKeyPress */);
+ updateBacklightState(inputDevice.getId(), index, false /* isTriggeredByKeyPress */);
if (DEBUG) {
Slog.d(TAG, "Restoring brightness level " + brightness.getAsInt());
}
@@ -217,14 +226,10 @@
if (!mIsInteractive) {
return;
}
- if (!mIsBacklightOn) {
- mIsBacklightOn = true;
- for (int i = 0; i < mKeyboardBacklights.size(); i++) {
- int deviceId = mKeyboardBacklights.keyAt(i);
- KeyboardBacklightState state = mKeyboardBacklights.valueAt(i);
- updateBacklightState(deviceId, state.mLight, state.mBrightnessLevel,
- false /* isTriggeredByKeyPress */);
- }
+ mIsBacklightOn = true;
+ for (int i = 0; i < mKeyboardBacklights.size(); i++) {
+ KeyboardBacklightState state = mKeyboardBacklights.valueAt(i);
+ state.onBacklightStateChanged();
}
mHandler.removeMessages(MSG_NOTIFY_USER_INACTIVITY);
mHandler.sendEmptyMessageAtTime(MSG_NOTIFY_USER_INACTIVITY,
@@ -232,14 +237,10 @@
}
private void handleUserInactivity() {
- if (mIsBacklightOn) {
- mIsBacklightOn = false;
- for (int i = 0; i < mKeyboardBacklights.size(); i++) {
- int deviceId = mKeyboardBacklights.keyAt(i);
- KeyboardBacklightState state = mKeyboardBacklights.valueAt(i);
- updateBacklightState(deviceId, state.mLight, state.mBrightnessLevel,
- false /* isTriggeredByKeyPress */);
- }
+ mIsBacklightOn = false;
+ for (int i = 0; i < mKeyboardBacklights.size(); i++) {
+ KeyboardBacklightState state = mKeyboardBacklights.valueAt(i);
+ state.onBacklightStateChanged();
}
}
@@ -310,7 +311,7 @@
return;
}
// The keyboard backlight was added or changed.
- mKeyboardBacklights.put(deviceId, new KeyboardBacklightState(keyboardBacklight));
+ mKeyboardBacklights.put(deviceId, new KeyboardBacklightState(deviceId, keyboardBacklight));
restoreBacklightBrightness(inputDevice, keyboardBacklight);
}
@@ -372,21 +373,14 @@
}
}
- private void updateBacklightState(int deviceId, Light light, int brightnessLevel,
+ private void updateBacklightState(int deviceId, int brightnessLevel,
boolean isTriggeredByKeyPress) {
KeyboardBacklightState state = mKeyboardBacklights.get(deviceId);
if (state == null) {
return;
}
- mNative.setLightColor(deviceId, light.getId(),
- mIsBacklightOn ? Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[brightnessLevel], 0, 0, 0)
- : 0);
- if (DEBUG) {
- Slog.d(TAG, "Changing state from " + state.mBrightnessLevel + " to " + brightnessLevel
- + "(isBacklightOn = " + mIsBacklightOn + ")");
- }
- state.mBrightnessLevel = brightnessLevel;
+ state.setBrightnessLevel(brightnessLevel);
synchronized (mKeyboardBacklightListenerRecords) {
for (int i = 0; i < mKeyboardBacklightListenerRecords.size(); i++) {
@@ -397,6 +391,10 @@
deviceId, callbackState, isTriggeredByKeyPress);
}
}
+
+ if (DEBUG) {
+ Slog.d(TAG, "Changing state from " + state.mBrightnessLevel + " to " + brightnessLevel);
+ }
}
private void onKeyboardBacklightListenerDied(int pid) {
@@ -436,10 +434,7 @@
@Override
public void dump(PrintWriter pw) {
IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
- ipw.println(
- TAG + ": " + mKeyboardBacklights.size() + " keyboard backlights, isBacklightOn = "
- + mIsBacklightOn);
-
+ ipw.println(TAG + ": " + mKeyboardBacklights.size() + " keyboard backlights");
ipw.increaseIndent();
for (int i = 0; i < mKeyboardBacklights.size(); i++) {
KeyboardBacklightState state = mKeyboardBacklights.valueAt(i);
@@ -448,6 +443,10 @@
ipw.decreaseIndent();
}
+ private static boolean isAnimationEnabled() {
+ return InputFeatureFlagProvider.isKeyboardBacklightAnimationEnabled();
+ }
+
// A record of a registered Keyboard backlight listener from one process.
private class KeyboardBacklightListenerRecord implements IBinder.DeathRecipient {
public final int mPid;
@@ -478,14 +477,55 @@
}
}
- private static class KeyboardBacklightState {
+ private class KeyboardBacklightState {
+ private final int mDeviceId;
private final Light mLight;
private int mBrightnessLevel;
+ private ValueAnimator mAnimator;
- KeyboardBacklightState(Light light) {
+ KeyboardBacklightState(int deviceId, Light light) {
+ mDeviceId = deviceId;
mLight = light;
}
+ private void onBacklightStateChanged() {
+ setBacklightValue(mIsBacklightOn ? BRIGHTNESS_VALUE_FOR_LEVEL[mBrightnessLevel] : 0);
+ }
+ private void setBrightnessLevel(int brightnessLevel) {
+ if (mIsBacklightOn) {
+ setBacklightValue(BRIGHTNESS_VALUE_FOR_LEVEL[brightnessLevel]);
+ }
+ mBrightnessLevel = brightnessLevel;
+ }
+
+ private void cancelAnimation() {
+ if (mAnimator != null && mAnimator.isRunning()) {
+ mAnimator.cancel();
+ }
+ }
+
+ private void setBacklightValue(int toValue) {
+ int fromValue = Color.alpha(mNative.getLightColor(mDeviceId, mLight.getId()));
+ if (fromValue == toValue) {
+ return;
+ }
+ if (isAnimationEnabled()) {
+ startAnimation(fromValue, toValue);
+ } else {
+ mNative.setLightColor(mDeviceId, mLight.getId(), Color.argb(toValue, 0, 0, 0));
+ }
+ }
+
+ private void startAnimation(int fromValue, int toValue) {
+ // Cancel any ongoing animation before starting a new one
+ cancelAnimation();
+ mAnimator = mAnimatorFactory.makeIntAnimator(fromValue, toValue);
+ mAnimator.addUpdateListener(
+ (animation) -> mNative.setLightColor(mDeviceId, mLight.getId(),
+ Color.argb((int) animation.getAnimatedValue(), 0, 0, 0)));
+ mAnimator.setDuration(TRANSITION_ANIMATION_DURATION_MILLIS).start();
+ }
+
@Override
public String toString() {
return "KeyboardBacklightState{Light=" + mLight.getId()
@@ -493,4 +533,9 @@
+ "}";
}
}
+
+ @VisibleForTesting
+ interface AnimatorFactory {
+ ValueAnimator makeIntAnimator(int from, int to);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt b/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
index 64c05dc..2726792 100644
--- a/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
@@ -16,6 +16,7 @@
package com.android.server.input
+import android.animation.ValueAnimator
import android.content.Context
import android.content.ContextWrapper
import android.graphics.Color
@@ -29,6 +30,7 @@
import android.os.test.TestLooper
import android.platform.test.annotations.Presubmit
import android.view.InputDevice
+import androidx.test.annotation.UiThreadTest
import androidx.test.core.app.ApplicationProvider
import com.android.server.input.KeyboardBacklightController.BRIGHTNESS_VALUE_FOR_LEVEL
import com.android.server.input.KeyboardBacklightController.USER_INACTIVITY_THRESHOLD_MILLIS
@@ -96,9 +98,11 @@
private lateinit var context: Context
private lateinit var dataStore: PersistentDataStore
private lateinit var testLooper: TestLooper
+ private val totalLevels = BRIGHTNESS_VALUE_FOR_LEVEL.size
private var lightColorMap: HashMap<Int, Int> = HashMap()
private var lastBacklightState: KeyboardBacklightState? = null
private var sysfsNodeChanges = 0
+ private var lastAnimationValues = IntArray(2)
@Before
fun setup() {
@@ -115,8 +119,8 @@
override fun finishWrite(fos: FileOutputStream?, success: Boolean) {}
})
testLooper = TestLooper()
- keyboardBacklightController =
- KeyboardBacklightController(context, native, dataStore, testLooper.looper)
+ keyboardBacklightController = KeyboardBacklightController(context, native, dataStore,
+ testLooper.looper, FakeAnimatorFactory())
InputManagerGlobal.resetInstance(iInputManager)
val inputManager = InputManager(context)
`when`(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager)
@@ -125,6 +129,10 @@
val args = it.arguments
lightColorMap.put(args[1] as Int, args[2] as Int)
}
+ `when`(native.getLightColor(anyInt(), anyInt())).thenAnswer {
+ val args = it.arguments
+ lightColorMap.getOrDefault(args[1] as Int, 0)
+ }
lightColorMap.clear()
`when`(native.sysfsNodeChanged(any())).then {
sysfsNodeChanges++
@@ -138,271 +146,287 @@
@Test
fun testKeyboardBacklightIncrementDecrement() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+ BacklightAnimationFlag(false).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- for (level in 1 until BRIGHTNESS_VALUE_FOR_LEVEL.size) {
+ for (level in 1 until totalLevels) {
+ incrementKeyboardBacklight(DEVICE_ID)
+ assertEquals(
+ "Light value for level $level mismatched",
+ Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
+ lightColorMap[LIGHT_ID]
+ )
+ assertEquals(
+ "Light value for level $level must be correctly stored in the datastore",
+ BRIGHTNESS_VALUE_FOR_LEVEL[level],
+ dataStore.getKeyboardBacklightBrightness(
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID
+ ).asInt
+ )
+ }
+
+ // Increment above max level
incrementKeyboardBacklight(DEVICE_ID)
assertEquals(
- "Light value for level $level mismatched",
- Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
+ "Light value for max level mismatched",
+ Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
lightColorMap[LIGHT_ID]
)
assertEquals(
- "Light value for level $level must be correctly stored in the datastore",
- BRIGHTNESS_VALUE_FOR_LEVEL[level],
+ "Light value for max level must be correctly stored in the datastore",
+ MAX_BRIGHTNESS,
dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID
).asInt
)
- }
- // Increment above max level
- incrementKeyboardBacklight(DEVICE_ID)
- assertEquals(
- "Light value for max level mismatched",
- Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
- assertEquals(
- "Light value for max level must be correctly stored in the datastore",
- MAX_BRIGHTNESS,
- dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
- ).asInt
- )
+ for (level in totalLevels - 2 downTo 0) {
+ decrementKeyboardBacklight(DEVICE_ID)
+ assertEquals(
+ "Light value for level $level mismatched",
+ Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
+ lightColorMap[LIGHT_ID]
+ )
+ assertEquals(
+ "Light value for level $level must be correctly stored in the datastore",
+ BRIGHTNESS_VALUE_FOR_LEVEL[level],
+ dataStore.getKeyboardBacklightBrightness(
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID
+ ).asInt
+ )
+ }
- for (level in BRIGHTNESS_VALUE_FOR_LEVEL.size - 2 downTo 0) {
+ // Decrement below min level
decrementKeyboardBacklight(DEVICE_ID)
assertEquals(
- "Light value for level $level mismatched",
- Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
+ "Light value for min level mismatched",
+ Color.argb(0, 0, 0, 0),
lightColorMap[LIGHT_ID]
)
assertEquals(
- "Light value for level $level must be correctly stored in the datastore",
- BRIGHTNESS_VALUE_FOR_LEVEL[level],
+ "Light value for min level must be correctly stored in the datastore",
+ 0,
dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID
).asInt
)
}
-
- // Decrement below min level
- decrementKeyboardBacklight(DEVICE_ID)
- assertEquals(
- "Light value for min level mismatched",
- Color.argb(0, 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
- assertEquals(
- "Light value for min level must be correctly stored in the datastore",
- 0,
- dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
- ).asInt
- )
}
@Test
fun testKeyboardWithoutBacklight() {
- val keyboardWithoutBacklight = createKeyboard(DEVICE_ID)
- val keyboardInputLight = createLight(LIGHT_ID, Light.LIGHT_TYPE_INPUT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithoutBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardInputLight))
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+ BacklightAnimationFlag(false).use {
+ val keyboardWithoutBacklight = createKeyboard(DEVICE_ID)
+ val keyboardInputLight = createLight(LIGHT_ID, Light.LIGHT_TYPE_INPUT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithoutBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardInputLight))
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- incrementKeyboardBacklight(DEVICE_ID)
- assertTrue("Non Keyboard backlights should not change", lightColorMap.isEmpty())
+ incrementKeyboardBacklight(DEVICE_ID)
+ assertTrue("Non Keyboard backlights should not change", lightColorMap.isEmpty())
+ }
}
@Test
fun testKeyboardWithMultipleLight() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- val keyboardInputLight = createLight(SECOND_LIGHT_ID, Light.LIGHT_TYPE_INPUT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(
- listOf(
- keyboardBacklight,
- keyboardInputLight
+ BacklightAnimationFlag(false).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ val keyboardInputLight = createLight(SECOND_LIGHT_ID, Light.LIGHT_TYPE_INPUT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(
+ listOf(
+ keyboardBacklight,
+ keyboardInputLight
+ )
)
- )
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- incrementKeyboardBacklight(DEVICE_ID)
- assertEquals("Only keyboard backlights should change", 1, lightColorMap.size)
- assertNotNull("Keyboard backlight should change", lightColorMap[LIGHT_ID])
- assertNull("Input lights should not change", lightColorMap[SECOND_LIGHT_ID])
+ incrementKeyboardBacklight(DEVICE_ID)
+ assertEquals("Only keyboard backlights should change", 1, lightColorMap.size)
+ assertNotNull("Keyboard backlight should change", lightColorMap[LIGHT_ID])
+ assertNull("Input lights should not change", lightColorMap[SECOND_LIGHT_ID])
+ }
}
@Test
fun testRestoreBacklightOnInputDeviceAdded() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ BacklightAnimationFlag(false).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- for (level in 1 until BRIGHTNESS_VALUE_FOR_LEVEL.size) {
- dataStore.setKeyboardBacklightBrightness(
+ for (level in 1 until totalLevels) {
+ dataStore.setKeyboardBacklightBrightness(
keyboardWithBacklight.descriptor,
LIGHT_ID,
BRIGHTNESS_VALUE_FOR_LEVEL[level] - 1
+ )
+
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+ keyboardBacklightController.notifyUserActivity()
+ testLooper.dispatchNext()
+ assertEquals(
+ "Keyboard backlight level should be restored to the level saved in the " +
+ "data store",
+ Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
+ lightColorMap[LIGHT_ID]
+ )
+ keyboardBacklightController.onInputDeviceRemoved(DEVICE_ID)
+ }
+ }
+ }
+
+ @Test
+ fun testRestoreBacklightOnInputDeviceChanged() {
+ BacklightAnimationFlag(false).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ dataStore.setKeyboardBacklightBrightness(
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID,
+ MAX_BRIGHTNESS
+ )
+
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+ keyboardBacklightController.notifyUserActivity()
+ testLooper.dispatchNext()
+ assertTrue(
+ "Keyboard backlight should not be changed until its added",
+ lightColorMap.isEmpty()
+ )
+
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ keyboardBacklightController.onInputDeviceChanged(DEVICE_ID)
+ keyboardBacklightController.notifyUserActivity()
+ testLooper.dispatchNext()
+ assertEquals(
+ "Keyboard backlight level should be restored to the level saved in the data store",
+ Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
+ lightColorMap[LIGHT_ID]
+ )
+ }
+ }
+
+ @Test
+ fun testKeyboardBacklight_registerUnregisterListener() {
+ BacklightAnimationFlag(false).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+
+ // Register backlight listener
+ val listener = KeyboardBacklightListener()
+ keyboardBacklightController.registerKeyboardBacklightListener(listener, 0)
+
+ lastBacklightState = null
+ keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID)
+ testLooper.dispatchNext()
+
+ assertEquals(
+ "Backlight state device Id should be $DEVICE_ID",
+ DEVICE_ID,
+ lastBacklightState!!.deviceId
+ )
+ assertEquals(
+ "Backlight state brightnessLevel should be " + 1,
+ 1,
+ lastBacklightState!!.brightnessLevel
+ )
+ assertEquals(
+ "Backlight state maxBrightnessLevel should be " + (totalLevels - 1),
+ (totalLevels - 1),
+ lastBacklightState!!.maxBrightnessLevel
+ )
+ assertEquals(
+ "Backlight state isTriggeredByKeyPress should be true",
+ true,
+ lastBacklightState!!.isTriggeredByKeyPress
+ )
+
+ // Unregister listener
+ keyboardBacklightController.unregisterKeyboardBacklightListener(listener, 0)
+
+ lastBacklightState = null
+ incrementKeyboardBacklight(DEVICE_ID)
+
+ assertNull("Listener should not receive any updates", lastBacklightState)
+ }
+ }
+
+ @Test
+ fun testKeyboardBacklight_userActivity() {
+ BacklightAnimationFlag(false).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ dataStore.setKeyboardBacklightBrightness(
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID,
+ MAX_BRIGHTNESS
)
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
keyboardBacklightController.notifyUserActivity()
testLooper.dispatchNext()
assertEquals(
- "Keyboard backlight level should be restored to the level saved in the data " +
- "store",
- Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
- lightColorMap[LIGHT_ID]
+ "Keyboard backlight level should be restored to the level saved in the data store",
+ Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
+ lightColorMap[LIGHT_ID]
)
- keyboardBacklightController.onInputDeviceRemoved(DEVICE_ID)
+
+ testLooper.moveTimeForward(USER_INACTIVITY_THRESHOLD_MILLIS + 1000)
+ testLooper.dispatchNext()
+ assertEquals(
+ "Keyboard backlight level should be turned off after inactivity",
+ 0,
+ lightColorMap[LIGHT_ID]
+ )
}
}
@Test
- fun testRestoreBacklightOnInputDeviceChanged() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- dataStore.setKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID,
- MAX_BRIGHTNESS
- )
-
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- keyboardBacklightController.notifyUserActivity()
- testLooper.dispatchNext()
- assertTrue(
- "Keyboard backlight should not be changed until its added",
- lightColorMap.isEmpty()
- )
-
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- keyboardBacklightController.onInputDeviceChanged(DEVICE_ID)
- keyboardBacklightController.notifyUserActivity()
- testLooper.dispatchNext()
- assertEquals(
- "Keyboard backlight level should be restored to the level saved in the data store",
- Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
- }
-
- @Test
- fun testKeyboardBacklight_registerUnregisterListener() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
-
- // Register backlight listener
- val listener = KeyboardBacklightListener()
- keyboardBacklightController.registerKeyboardBacklightListener(listener, 0)
-
- lastBacklightState = null
- keyboardBacklightController.incrementKeyboardBacklight(DEVICE_ID)
- testLooper.dispatchNext()
-
- assertEquals(
- "Backlight state device Id should be $DEVICE_ID",
- DEVICE_ID,
- lastBacklightState!!.deviceId
- )
- assertEquals(
- "Backlight state brightnessLevel should be " + 1,
- 1,
- lastBacklightState!!.brightnessLevel
- )
- assertEquals(
- "Backlight state maxBrightnessLevel should be " + (BRIGHTNESS_VALUE_FOR_LEVEL.size - 1),
- (BRIGHTNESS_VALUE_FOR_LEVEL.size - 1),
- lastBacklightState!!.maxBrightnessLevel
- )
- assertEquals(
- "Backlight state isTriggeredByKeyPress should be true",
- true,
- lastBacklightState!!.isTriggeredByKeyPress
- )
-
- // Unregister listener
- keyboardBacklightController.unregisterKeyboardBacklightListener(listener, 0)
-
- lastBacklightState = null
- incrementKeyboardBacklight(DEVICE_ID)
-
- assertNull("Listener should not receive any updates", lastBacklightState)
- }
-
- @Test
- fun testKeyboardBacklight_userActivity() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- dataStore.setKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID,
- MAX_BRIGHTNESS
- )
-
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- keyboardBacklightController.notifyUserActivity()
- testLooper.dispatchNext()
- assertEquals(
- "Keyboard backlight level should be restored to the level saved in the data store",
- Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
-
- testLooper.moveTimeForward(USER_INACTIVITY_THRESHOLD_MILLIS + 1000)
- testLooper.dispatchNext()
- assertEquals(
- "Keyboard backlight level should be turned off after inactivity",
- 0,
- lightColorMap[LIGHT_ID]
- )
- }
-
- @Test
fun testKeyboardBacklight_displayOnOff() {
- val keyboardWithBacklight = createKeyboard(DEVICE_ID)
- val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
- `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
- `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- dataStore.setKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID,
- MAX_BRIGHTNESS
- )
+ BacklightAnimationFlag(false).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ dataStore.setKeyboardBacklightBrightness(
+ keyboardWithBacklight.descriptor,
+ LIGHT_ID,
+ MAX_BRIGHTNESS
+ )
- keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- keyboardBacklightController.handleInteractiveStateChange(true /* isDisplayOn */)
- assertEquals(
- "Keyboard backlight level should be restored to the level saved in the data " +
- "store when display turned on",
- Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+ keyboardBacklightController.handleInteractiveStateChange(true /* isDisplayOn */)
+ assertEquals(
+ "Keyboard backlight level should be restored to the level saved in the data " +
+ "store when display turned on",
+ Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
+ lightColorMap[LIGHT_ID]
+ )
- keyboardBacklightController.handleInteractiveStateChange(false /* isDisplayOn */)
- assertEquals(
- "Keyboard backlight level should be turned off after display is turned off",
- 0,
- lightColorMap[LIGHT_ID]
- )
+ keyboardBacklightController.handleInteractiveStateChange(false /* isDisplayOn */)
+ assertEquals(
+ "Keyboard backlight level should be turned off after display is turned off",
+ 0,
+ lightColorMap[LIGHT_ID]
+ )
+ }
}
@Test
@@ -463,6 +487,30 @@
)
}
+ @Test
+ @UiThreadTest
+ fun testKeyboardBacklightAnimation_onChangeLevels() {
+ BacklightAnimationFlag(true).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+
+ incrementKeyboardBacklight(DEVICE_ID)
+ assertEquals(
+ "Should start animation from level 0",
+ BRIGHTNESS_VALUE_FOR_LEVEL[0],
+ lastAnimationValues[0]
+ )
+ assertEquals(
+ "Should start animation to level 1",
+ BRIGHTNESS_VALUE_FOR_LEVEL[1],
+ lastAnimationValues[1]
+ )
+ }
+ }
+
inner class KeyboardBacklightListener : IKeyboardBacklightListener.Stub() {
override fun onBrightnessChanged(
deviceId: Int,
@@ -496,4 +544,22 @@
val maxBrightnessLevel: Int,
val isTriggeredByKeyPress: Boolean
)
+
+ private inner class BacklightAnimationFlag constructor(enabled: Boolean) : AutoCloseable {
+ init {
+ InputFeatureFlagProvider.setKeyboardBacklightAnimationEnabled(enabled)
+ }
+
+ override fun close() {
+ InputFeatureFlagProvider.clearOverrides()
+ }
+ }
+
+ private inner class FakeAnimatorFactory : KeyboardBacklightController.AnimatorFactory {
+ override fun makeIntAnimator(from: Int, to: Int): ValueAnimator {
+ lastAnimationValues[0] = from
+ lastAnimationValues[1] = to
+ return ValueAnimator.ofInt(from, to)
+ }
+ }
}